Studio: add French, German, Spanish, Hindi, Arabic, Russian and Korean display languages (#7076)
* Studio: add 7 display languages, complete and fix existing locales Adds fully translated French, German, Spanish, Hindi, Arabic, Russian and Korean locales. Fills in all missing keys for zh-CN (113), ja (71) and pt-BR (47), fixes translation errors found in review, and reorders the language dropdown by popularity. All overlays pass check-parity with zero missing keys and zero placeholder mismatches. * Studio: default display language to auto detect The language preference now defaults to auto and resolves against the browser language list, with exact tag match first and language subtag match second (pt-PT resolves to pt-BR, zh-TW to zh-CN). Auto detect is the first dropdown option and is translated in every locale. Explicit choices still persist and sync; personalization sync now round trips the preference instead of the resolved locale so auto stays auto across devices. Auto mode also follows browser languagechange events. * Studio: guard import.meta.env in translate for non-Vite contexts translate() read import.meta.env.DEV directly, which throws when the module runs outside Vite (SSR or Node tooling). Optional-chain it so the dev-only warning is skipped and translation still works everywhere. * Studio: RTL for Arabic, translate recipes, keep Traditional Chinese off zh-CN - Sync document dir from a per-locale dir field so Arabic mirrors the layout instead of rendering RTL text in an LTR shell. - Translate the recipes nav label in fr, de, ko and hi to match the other locales (Recettes, Rezepte, and native forms). - Detection no longer maps Traditional Chinese (zh-Hant / zh-TW / zh-HK / zh-MO) to Simplified zh-CN; those tags fall through to the next preferred language. Simplified tags (zh, zh-CN, zh-SG, zh-Hans) still resolve to zh-CN. * Studio: don't treat legacy synced English as an explicit language pick The old sync serialized the resolved locale on every save, so existing profiles carry appearance.language 'en' even when the user never chose a language. Hydrating that as a pinned locale forced non-English browsers back to English under the new Auto detect default. Payloads now carry version 2 (the preference itself); on hydrate a version 1 'en' maps to auto, while explicit picks and all version 2 values are kept as-is. * Studio: persist only known language codes from the locale table normalizePreference now returns a value re-derived from the LOCALES keys instead of the raw input. It stays functionally identical (the stored value was already whitelisted) but makes it explicit that only known, non-sensitive language codes are written to localStorage, and clears a false-positive clear-text-storage scan on the persistence path. * Studio i18n: fix Train label transliteration and tidy locale consistency - ja and hi: the nav and route Train label used the railway transliteration (トレイン and ट्रेन); switch to the training term already used everywhere else in each file (トレーニング, ट्रेनिंग). - zh-CN: keep VRAM in English to match every other locale and the PR's own keep-English rule, and drop an extra clause added to the upload size hint so it matches the English source. - hi: translate Recents to हाल के in the export and import section to match the sidebar label, and point users to the Configure tab by its translated name (कॉन्फ़िगर). - ru: reword the preview sharing hint to avoid the "disable to disable" repetition. i18n parity and the type checked build stay green. * Studio i18n: keep Arabic layout LTR until physical-direction CSS is converted Setting ar to dir rtl only mirrors the flex based shell, sidebar and settings dialog. The shared select, dialog and dropdown primitives use physical-direction utilities (right-2, top-5 right-5, ml-auto) that do not flip under dir rtl, so chevrons, close buttons and check marks land on the wrong side. Keep Arabic on an LTR layout for now, matching the original plan in this PR. Arabic text still renders right to left per element via bidi and chat content keeps dir auto, so nothing regresses. Full layout mirroring can follow once the physical-direction classes are converted to logical ones. * Studio i18n: do not let a generic zh after a Traditional tag pick Simplified navigator.languages can be a list like ['zh-TW', 'zh', 'en-US']. The zh-TW pass already falls through, but the bare zh then reached the language-subtag match and selected zh-CN, so Traditional Chinese users still got Simplified and the guard was defeated. detectLocale now remembers when a Traditional tag was seen and skips a later bare zh, so detection keeps falling through to the next non-Chinese language. A lone bare zh, and explicit zh-CN or zh-Hans fallbacks, still resolve to Simplified as before. * Studio i18n: collapse two locale comments to a single line The Arabic dir note in messages.ts and the bare-zh note in locale-store.ts were two lines each; tighten each to one. Comment only, no behavior change. * Studio i18n: translate Hindi strings that were left in English Seventeen hi.ts labels stayed in English while all the other locales translated them: the training parameter labels (Grad Accum, Grad Norm, Grad Checkpoint, Eval Loss, Clip p95/p99, Seed, Continued Pretraining), the API example labels (curl/Python/JavaScript + tools/advanced), Hugging Face token, the VRAM estimate and the training terminal start line. Parity only checks key/placeholder presence so it did not catch these. Brand and technical tokens (curl, Python, VRAM, Loss, p95/p99, Hugging Face, unsloth) stay in English as elsewhere. --------- Co-authored-by: danielhanchen <danielhanchen@gmail.com>
This commit is contained in:
parent
fea7d9ba34
commit
6e375a5b17
17 changed files with 7684 additions and 81 deletions
|
|
@ -9,12 +9,12 @@ import {
|
|||
type Theme,
|
||||
} from "@/features/settings";
|
||||
import {
|
||||
DEFAULT_LOCALE,
|
||||
getLocale,
|
||||
isSupportedLocale,
|
||||
DEFAULT_LOCALE_PREFERENCE,
|
||||
getLocalePreference,
|
||||
isLocalePreference,
|
||||
setLocale,
|
||||
useLocale,
|
||||
type Locale,
|
||||
useLocalePreference,
|
||||
type LocalePreference,
|
||||
} from "@/i18n";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
|
|
@ -25,6 +25,11 @@ import type { AvatarShape } from "../stores/user-profile-store";
|
|||
|
||||
const PUSH_DEBOUNCE_MS = 800;
|
||||
|
||||
// Version 2 payloads store the language preference ("auto" or a pinned
|
||||
// locale). Version 1 always serialized the resolved locale, so its "en" is
|
||||
// usually the old default rather than an explicit pick.
|
||||
const PERSONALIZATION_VERSION = 2;
|
||||
|
||||
type ProfileSnapshot = {
|
||||
displayName: string;
|
||||
nickname: string;
|
||||
|
|
@ -110,10 +115,10 @@ function profileSnapshot(): ProfileSnapshot {
|
|||
function payload(
|
||||
profile: ProfileSnapshot,
|
||||
theme: Theme,
|
||||
language: Locale | null,
|
||||
language: LocalePreference | null,
|
||||
): PersonalizationWrite {
|
||||
return {
|
||||
version: 1,
|
||||
version: PERSONALIZATION_VERSION,
|
||||
profile: normalizeProfile(profile),
|
||||
appearance: { theme, language },
|
||||
};
|
||||
|
|
@ -123,10 +128,23 @@ function serialized(data: PersonalizationWrite): string {
|
|||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
// Version 1 clients wrote language on every save, so a legacy "en" usually
|
||||
// means the user never picked a language. Map it to auto; explicit picks of
|
||||
// other locales (the old default was English) are kept. Version 2 payloads
|
||||
// are trusted verbatim, so a deliberate English pick stays pinned.
|
||||
export function remoteLanguagePreference(
|
||||
version: unknown,
|
||||
language: unknown,
|
||||
): unknown {
|
||||
const isLegacy = typeof version !== "number" || version < 2;
|
||||
if (isLegacy && language === "en") return DEFAULT_LOCALE_PREFERENCE;
|
||||
return language;
|
||||
}
|
||||
|
||||
function hasLocalSettings(
|
||||
profile: ProfileSnapshot,
|
||||
theme: Theme,
|
||||
language: Locale,
|
||||
language: LocalePreference,
|
||||
): boolean {
|
||||
return Boolean(
|
||||
profile.displayName ||
|
||||
|
|
@ -134,7 +152,7 @@ function hasLocalSettings(
|
|||
profile.avatarDataUrl ||
|
||||
profile.avatarShape !== "circle" ||
|
||||
theme !== "system" ||
|
||||
language !== DEFAULT_LOCALE,
|
||||
language !== DEFAULT_LOCALE_PREFERENCE,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +162,7 @@ export function usePersonalizationSync(enabled: boolean): void {
|
|||
const avatarDataUrl = useUserProfileStore((s) => s.avatarDataUrl);
|
||||
const avatarShape = useUserProfileStore((s) => s.avatarShape);
|
||||
const { theme } = useTheme();
|
||||
const language = useLocale();
|
||||
const language = useLocalePreference();
|
||||
const [hydratedGeneration, setHydratedGeneration] = useState(0);
|
||||
const authGenerationRef = useRef(0);
|
||||
const latestThemeRef = useRef(theme);
|
||||
|
|
@ -191,8 +209,12 @@ export function usePersonalizationSync(enabled: boolean): void {
|
|||
avatarShape: remote.profile.avatarShape === "rounded" ? "rounded" : "circle",
|
||||
};
|
||||
const nextTheme = remote.appearance.theme;
|
||||
const nextLanguage = isSupportedLocale(remote.appearance.language)
|
||||
? remote.appearance.language
|
||||
const remoteLanguage = remoteLanguagePreference(
|
||||
remote.version,
|
||||
remote.appearance.language,
|
||||
);
|
||||
const nextLanguage = isLocalePreference(remoteLanguage)
|
||||
? remoteLanguage
|
||||
: latestLanguageRef.current;
|
||||
useUserProfileStore.setState(nextProfile);
|
||||
if (nextTheme !== latestThemeRef.current) setTheme(nextTheme);
|
||||
|
|
@ -207,7 +229,7 @@ export function usePersonalizationSync(enabled: boolean): void {
|
|||
useUserProfileStore.setState(nextProfile);
|
||||
}
|
||||
const nextTheme = latestThemeRef.current;
|
||||
const nextLanguage = getLocale();
|
||||
const nextLanguage = getLocalePreference();
|
||||
const nextPayload = payload(nextProfile, nextTheme, nextLanguage);
|
||||
const nextSerialized = serialized(nextPayload);
|
||||
if (hasLocalSettings(nextProfile, nextTheme, nextLanguage)) {
|
||||
|
|
|
|||
|
|
@ -9,22 +9,23 @@ import {
|
|||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import {
|
||||
AUTO_LOCALE,
|
||||
LOCALES,
|
||||
isSupportedLocale,
|
||||
isLocalePreference,
|
||||
setLocale,
|
||||
useT,
|
||||
useLocale,
|
||||
useLocalePreference,
|
||||
} from "@/i18n";
|
||||
|
||||
export function LanguageSelect() {
|
||||
const t = useT();
|
||||
const locale = useLocale();
|
||||
const preference = useLocalePreference();
|
||||
|
||||
return (
|
||||
<Select
|
||||
value={locale}
|
||||
value={preference}
|
||||
onValueChange={(value) => {
|
||||
if (isSupportedLocale(value)) setLocale(value);
|
||||
if (isLocalePreference(value)) setLocale(value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger
|
||||
|
|
@ -35,6 +36,9 @@ export function LanguageSelect() {
|
|||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value={AUTO_LOCALE}>
|
||||
{t("settings.appearance.language.autoDetect")}
|
||||
</SelectItem>
|
||||
{Object.entries(LOCALES).map(([value, metadata]) => (
|
||||
<SelectItem key={value} value={value}>
|
||||
{metadata.nativeLabel}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@ import { en } from "./locales/en.ts";
|
|||
import { zhCN } from "./locales/zh-CN.ts";
|
||||
import { ptBR } from "./locales/pt-br.ts";
|
||||
import { ja } from "./locales/ja.ts";
|
||||
import { es } from "./locales/es.ts";
|
||||
import { hi } from "./locales/hi.ts";
|
||||
import { ar } from "./locales/ar.ts";
|
||||
import { fr } from "./locales/fr.ts";
|
||||
import { ru } from "./locales/ru.ts";
|
||||
import { de } from "./locales/de.ts";
|
||||
import { ko } from "./locales/ko.ts";
|
||||
|
||||
type Tree = { readonly [k: string]: string | Tree };
|
||||
|
||||
|
|
@ -89,10 +96,17 @@ function checkExtras(
|
|||
}
|
||||
}
|
||||
|
||||
const overlays: Record<string, Tree> = {
|
||||
const overlays: Record<string, Tree> = {
|
||||
"zh-CN": zhCN as unknown as Tree,
|
||||
"pt-BR": ptBR as unknown as Tree,
|
||||
"ja": ja as unknown as Tree,
|
||||
es: es as unknown as Tree,
|
||||
hi: hi as unknown as Tree,
|
||||
ar: ar as unknown as Tree,
|
||||
fr: fr as unknown as Tree,
|
||||
ru: ru as unknown as Tree,
|
||||
de: de as unknown as Tree,
|
||||
ko: ko as unknown as Tree,
|
||||
};
|
||||
let anyError = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,20 @@ import type { InterpolationValues } from "./types";
|
|||
import type { TranslationKey } from "./messages";
|
||||
|
||||
export {
|
||||
AUTO_LOCALE,
|
||||
DEFAULT_LOCALE,
|
||||
DEFAULT_LOCALE_PREFERENCE,
|
||||
LOCALE_STORAGE_KEY,
|
||||
getLocale,
|
||||
getLocalePreference,
|
||||
initializeLocale,
|
||||
isLocalePreference,
|
||||
setLocale,
|
||||
subscribeLocale,
|
||||
useLocale,
|
||||
useLocalePreference,
|
||||
} from "./locale-store";
|
||||
export type { LocalePreference } from "./locale-store";
|
||||
export {
|
||||
LOCALES,
|
||||
isSupportedLocale,
|
||||
|
|
|
|||
|
|
@ -2,32 +2,94 @@
|
|||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import { useSyncExternalStore } from "react";
|
||||
import { isSupportedLocale, type Locale } from "./messages";
|
||||
import { isSupportedLocale, LOCALES, type Locale } from "./messages";
|
||||
|
||||
export const DEFAULT_LOCALE: Locale = "en";
|
||||
export const AUTO_LOCALE = "auto";
|
||||
export const LOCALE_STORAGE_KEY = "unsloth_locale";
|
||||
|
||||
export type LocalePreference = Locale | typeof AUTO_LOCALE;
|
||||
|
||||
export const DEFAULT_LOCALE_PREFERENCE: LocalePreference = AUTO_LOCALE;
|
||||
|
||||
const subscribers = new Set<() => void>();
|
||||
|
||||
let currentPreference: LocalePreference = DEFAULT_LOCALE_PREFERENCE;
|
||||
let currentLocale: Locale = DEFAULT_LOCALE;
|
||||
let isStorageListenerActive = false;
|
||||
let areListenersActive = false;
|
||||
|
||||
function normalizeLocale(value: unknown): Locale {
|
||||
return isSupportedLocale(value) ? value : DEFAULT_LOCALE;
|
||||
export function isLocalePreference(value: unknown): value is LocalePreference {
|
||||
return value === AUTO_LOCALE || isSupportedLocale(value);
|
||||
}
|
||||
|
||||
function readStoredLocale(): Locale {
|
||||
function isTraditionalChinese(lowerTag: string): boolean {
|
||||
if (lowerTag.includes("hant")) return true;
|
||||
if (lowerTag.includes("hans")) return false;
|
||||
const parts = lowerTag.split("-");
|
||||
return parts.includes("tw") || parts.includes("hk") || parts.includes("mo");
|
||||
}
|
||||
|
||||
function matchLocale(tag: string): Locale | null {
|
||||
const locales = Object.keys(LOCALES) as Locale[];
|
||||
const lower = tag.toLowerCase();
|
||||
const exact = locales.find((locale) => locale.toLowerCase() === lower);
|
||||
if (exact) return exact;
|
||||
const language = lower.split("-")[0];
|
||||
// We only ship Simplified Chinese. Don't hand it to Traditional Chinese
|
||||
// (zh-Hant / zh-TW / zh-HK / zh-MO) users; let them fall through instead.
|
||||
if (language === "zh" && isTraditionalChinese(lower)) return null;
|
||||
return (
|
||||
locales.find((locale) => locale.toLowerCase().split("-")[0] === language) ??
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
function detectLocale(): Locale {
|
||||
const navigatorRef = globalThis.navigator;
|
||||
const tags = navigatorRef?.languages?.length
|
||||
? navigatorRef.languages
|
||||
: navigatorRef?.language
|
||||
? [navigatorRef.language]
|
||||
: [];
|
||||
let sawTraditionalChinese = false;
|
||||
for (const tag of tags) {
|
||||
const lower = tag.toLowerCase();
|
||||
if (lower.split("-")[0] === "zh" && isTraditionalChinese(lower)) {
|
||||
sawTraditionalChinese = true;
|
||||
} else if (sawTraditionalChinese && lower === "zh") {
|
||||
// Bare zh after a Traditional tag is the browser's base-subtag fallback, not a Simplified request; skip it.
|
||||
continue;
|
||||
}
|
||||
const match = matchLocale(tag);
|
||||
if (match) return match;
|
||||
}
|
||||
return DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
function normalizePreference(value: unknown): LocalePreference {
|
||||
if (value === AUTO_LOCALE) return AUTO_LOCALE;
|
||||
// Return a value re-derived from our own locale table rather than the raw
|
||||
// input, so only known language codes are ever persisted.
|
||||
const locales = Object.keys(LOCALES) as Locale[];
|
||||
return locales.find((locale) => locale === value) ?? DEFAULT_LOCALE_PREFERENCE;
|
||||
}
|
||||
|
||||
function resolvePreference(preference: LocalePreference): Locale {
|
||||
return preference === AUTO_LOCALE ? detectLocale() : preference;
|
||||
}
|
||||
|
||||
function readStoredPreference(): LocalePreference {
|
||||
try {
|
||||
const stored = globalThis.localStorage?.getItem(LOCALE_STORAGE_KEY) ?? null;
|
||||
return normalizeLocale(stored);
|
||||
return normalizePreference(stored);
|
||||
} catch {
|
||||
return DEFAULT_LOCALE;
|
||||
return DEFAULT_LOCALE_PREFERENCE;
|
||||
}
|
||||
}
|
||||
|
||||
function writeStoredLocale(locale: Locale): void {
|
||||
function writeStoredPreference(preference: LocalePreference): void {
|
||||
try {
|
||||
globalThis.localStorage?.setItem(LOCALE_STORAGE_KEY, locale);
|
||||
globalThis.localStorage?.setItem(LOCALE_STORAGE_KEY, preference);
|
||||
} catch {
|
||||
// localStorage 可能被禁用;失败只影响持久化,不影响当前会话语言。
|
||||
}
|
||||
|
|
@ -36,14 +98,17 @@ function writeStoredLocale(locale: Locale): void {
|
|||
function syncDocumentLang(locale: Locale): void {
|
||||
if (typeof document === "undefined") return;
|
||||
document.documentElement.lang = locale;
|
||||
document.documentElement.dir = LOCALES[locale].dir;
|
||||
}
|
||||
|
||||
function notifySubscribers(): void {
|
||||
for (const subscriber of subscribers) subscriber();
|
||||
}
|
||||
|
||||
function updateCurrentLocale(locale: Locale): void {
|
||||
if (locale === currentLocale) return;
|
||||
function applyPreference(preference: LocalePreference): void {
|
||||
const locale = resolvePreference(preference);
|
||||
if (preference === currentPreference && locale === currentLocale) return;
|
||||
currentPreference = preference;
|
||||
currentLocale = locale;
|
||||
syncDocumentLang(locale);
|
||||
notifySubscribers();
|
||||
|
|
@ -53,8 +118,8 @@ function isLocaleStorageEvent(event: StorageEvent): boolean {
|
|||
if (event.key !== LOCALE_STORAGE_KEY && event.key !== null) return false;
|
||||
if (!event.storageArea || typeof window === "undefined") return true;
|
||||
// Accessing window.localStorage can throw in privacy-restricted contexts
|
||||
// where storage is blocked; mirror the try/catch in readStoredLocale/
|
||||
// writeStoredLocale so storage-event handling is just as resilient.
|
||||
// where storage is blocked; mirror the try/catch in readStoredPreference/
|
||||
// writeStoredPreference so storage-event handling is just as resilient.
|
||||
try {
|
||||
return event.storageArea === window.localStorage;
|
||||
} catch {
|
||||
|
|
@ -64,21 +129,35 @@ function isLocaleStorageEvent(event: StorageEvent): boolean {
|
|||
|
||||
function handleStorageEvent(event: StorageEvent): void {
|
||||
if (!isLocaleStorageEvent(event)) return;
|
||||
const nextLocale =
|
||||
event.key === null ? DEFAULT_LOCALE : normalizeLocale(event.newValue);
|
||||
updateCurrentLocale(nextLocale);
|
||||
const nextPreference =
|
||||
event.key === null
|
||||
? DEFAULT_LOCALE_PREFERENCE
|
||||
: normalizePreference(event.newValue);
|
||||
applyPreference(nextPreference);
|
||||
}
|
||||
|
||||
function startStorageListener(): void {
|
||||
if (isStorageListenerActive || typeof window === "undefined") return;
|
||||
function handleLanguageChange(): void {
|
||||
// Only auto mode tracks the browser language.
|
||||
if (currentPreference !== AUTO_LOCALE) return;
|
||||
const locale = detectLocale();
|
||||
if (locale === currentLocale) return;
|
||||
currentLocale = locale;
|
||||
syncDocumentLang(locale);
|
||||
notifySubscribers();
|
||||
}
|
||||
|
||||
function startListeners(): void {
|
||||
if (areListenersActive || typeof window === "undefined") return;
|
||||
window.addEventListener("storage", handleStorageEvent);
|
||||
isStorageListenerActive = true;
|
||||
window.addEventListener("languagechange", handleLanguageChange);
|
||||
areListenersActive = true;
|
||||
}
|
||||
|
||||
function stopStorageListener(): void {
|
||||
if (!isStorageListenerActive || typeof window === "undefined") return;
|
||||
function stopListeners(): void {
|
||||
if (!areListenersActive || typeof window === "undefined") return;
|
||||
window.removeEventListener("storage", handleStorageEvent);
|
||||
isStorageListenerActive = false;
|
||||
window.removeEventListener("languagechange", handleLanguageChange);
|
||||
areListenersActive = false;
|
||||
}
|
||||
|
||||
function getLocaleSnapshot(): Locale {
|
||||
|
|
@ -89,35 +168,49 @@ function getServerLocaleSnapshot(): Locale {
|
|||
return DEFAULT_LOCALE;
|
||||
}
|
||||
|
||||
function getPreferenceSnapshot(): LocalePreference {
|
||||
return currentPreference;
|
||||
}
|
||||
|
||||
function getServerPreferenceSnapshot(): LocalePreference {
|
||||
return DEFAULT_LOCALE_PREFERENCE;
|
||||
}
|
||||
|
||||
export function subscribeLocale(listener: () => void): () => void {
|
||||
const shouldStartStorageListener = subscribers.size === 0;
|
||||
const shouldStartListeners = subscribers.size === 0;
|
||||
subscribers.add(listener);
|
||||
if (shouldStartStorageListener) startStorageListener();
|
||||
if (shouldStartListeners) startListeners();
|
||||
|
||||
return () => {
|
||||
subscribers.delete(listener);
|
||||
if (subscribers.size === 0) stopStorageListener();
|
||||
if (subscribers.size === 0) stopListeners();
|
||||
};
|
||||
}
|
||||
|
||||
export function initializeLocale(): Locale {
|
||||
const nextLocale = readStoredLocale();
|
||||
currentLocale = nextLocale;
|
||||
syncDocumentLang(nextLocale);
|
||||
const preference = readStoredPreference();
|
||||
currentPreference = preference;
|
||||
currentLocale = resolvePreference(preference);
|
||||
syncDocumentLang(currentLocale);
|
||||
notifySubscribers();
|
||||
return nextLocale;
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
export function getLocale(): Locale {
|
||||
return currentLocale;
|
||||
}
|
||||
|
||||
export function setLocale(locale: Locale): void {
|
||||
const requestedLocale = normalizeLocale(locale);
|
||||
writeStoredLocale(requestedLocale);
|
||||
export function getLocalePreference(): LocalePreference {
|
||||
return currentPreference;
|
||||
}
|
||||
|
||||
currentLocale = requestedLocale;
|
||||
syncDocumentLang(requestedLocale);
|
||||
export function setLocale(preference: LocalePreference): void {
|
||||
const requestedPreference = normalizePreference(preference);
|
||||
writeStoredPreference(requestedPreference);
|
||||
|
||||
currentPreference = requestedPreference;
|
||||
currentLocale = resolvePreference(requestedPreference);
|
||||
syncDocumentLang(currentLocale);
|
||||
notifySubscribers();
|
||||
}
|
||||
|
||||
|
|
@ -128,3 +221,11 @@ export function useLocale(): Locale {
|
|||
getServerLocaleSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
export function useLocalePreference(): LocalePreference {
|
||||
return useSyncExternalStore(
|
||||
subscribeLocale,
|
||||
getPreferenceSnapshot,
|
||||
getServerPreferenceSnapshot,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
1001
studio/frontend/src/i18n/locales/ar.ts
Normal file
1001
studio/frontend/src/i18n/locales/ar.ts
Normal file
File diff suppressed because it is too large
Load diff
1042
studio/frontend/src/i18n/locales/de.ts
Normal file
1042
studio/frontend/src/i18n/locales/de.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -269,6 +269,7 @@ export const en = {
|
|||
title: "Language",
|
||||
label: "Display language",
|
||||
description: "The language used by Unsloth.",
|
||||
autoDetect: "Auto detect",
|
||||
},
|
||||
layout: {
|
||||
title: "Layout",
|
||||
|
|
|
|||
1043
studio/frontend/src/i18n/locales/es.ts
Normal file
1043
studio/frontend/src/i18n/locales/es.ts
Normal file
File diff suppressed because it is too large
Load diff
1038
studio/frontend/src/i18n/locales/fr.ts
Normal file
1038
studio/frontend/src/i18n/locales/fr.ts
Normal file
File diff suppressed because it is too large
Load diff
999
studio/frontend/src/i18n/locales/hi.ts
Normal file
999
studio/frontend/src/i18n/locales/hi.ts
Normal file
|
|
@ -0,0 +1,999 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import type { DeepPartialMessageTree } from "../types";
|
||||
import type { en } from "./en";
|
||||
|
||||
export const hi = {
|
||||
common: {
|
||||
cancel: "रद्द करें",
|
||||
close: "बंद करें",
|
||||
delete: "हटाएं",
|
||||
done: "पूर्ण",
|
||||
error: "त्रुटि",
|
||||
export: "एक्सपोर्ट करें",
|
||||
help: "सहायता",
|
||||
loading: "लोड हो रहा है...",
|
||||
new: "नया",
|
||||
rename: "नाम बदलें",
|
||||
save: "सहेजें",
|
||||
saving: "सहेजा जा रहा है...",
|
||||
search: "खोजें",
|
||||
shutdown: "शटडाउन",
|
||||
},
|
||||
shell: {
|
||||
beta: "BETA",
|
||||
brand: "unsloth",
|
||||
product: "Unsloth Studio",
|
||||
accountMenu: "{name} खाता मेनू",
|
||||
updateAvailable: "अपडेट उपलब्ध है",
|
||||
aria: {
|
||||
home: "Unsloth होम",
|
||||
closeSidebar: "साइडबार बंद करें",
|
||||
openSidebar: "साइडबार खोलें",
|
||||
chatOptions: "चैट विकल्प",
|
||||
runOptions: "रन विकल्प",
|
||||
},
|
||||
navigation: {
|
||||
newChat: "नई चैट",
|
||||
returnToChat: "चैट पर लौटें",
|
||||
compare: "तुलना करें",
|
||||
search: "खोजें",
|
||||
hub: "Hub",
|
||||
train: "ट्रेनिंग",
|
||||
recipes: "रेसिपी",
|
||||
export: "एक्सपोर्ट",
|
||||
recents: "हाल के",
|
||||
noChatsYet: "अभी तक कोई चैट नहीं",
|
||||
settings: "सेटिंग्स",
|
||||
api: "API",
|
||||
lightMode: "लाइट मोड",
|
||||
darkMode: "डार्क मोड",
|
||||
guidedTour: "गाइडेड टूर",
|
||||
help: "सहायता",
|
||||
logOut: "लॉग आउट",
|
||||
shutdown: "शटडाउन",
|
||||
},
|
||||
notFound: {
|
||||
title: "पेज नहीं मिला",
|
||||
description: "{path} मौजूद नहीं है।",
|
||||
backToChat: "चैट पर वापस जाएं",
|
||||
},
|
||||
dialog: {
|
||||
deleteChat: {
|
||||
title: "चैट हटाएं",
|
||||
description: 'क्या आप वाकई इस चैट "{name}" को हटाना चाहते हैं?',
|
||||
},
|
||||
deleteRun: {
|
||||
title: "ट्रेनिंग रन हटाएं",
|
||||
description: 'क्या आप वाकई इस रन "{name}" को हटाना चाहते हैं?',
|
||||
},
|
||||
renameChat: {
|
||||
title: "चैट का नाम बदलें",
|
||||
placeholder: "चैट शीर्षक",
|
||||
},
|
||||
renameRun: {
|
||||
title: "रन का नाम बदलें",
|
||||
placeholder: "रन का नाम",
|
||||
},
|
||||
},
|
||||
toast: {
|
||||
cannotDeleteRunningRun: "चल रही ट्रेनिंग रन को हटाया नहीं जा सकता",
|
||||
failedToDeleteChat: "चैट हटाने में विफल",
|
||||
failedToDeleteRun: "रन हटाने में विफल",
|
||||
failedToRenameChat: "चैट का नाम बदलने में विफल",
|
||||
failedToRenameRun: "रन का नाम बदलने में विफल",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
title: "सेटिंग्स",
|
||||
dialog: {
|
||||
title: "सेटिंग्स",
|
||||
description: "अपनी Unsloth प्राथमिकताएं प्रबंधित करें।",
|
||||
closeAriaLabel: "सेटिंग्स बंद करें",
|
||||
},
|
||||
tabs: {
|
||||
general: "सामान्य",
|
||||
profile: "प्रोफ़ाइल",
|
||||
appearance: "रूप-रंग",
|
||||
resources: "सिस्टम",
|
||||
chat: "चैट",
|
||||
connections: "कनेक्शन",
|
||||
apiKeys: "API",
|
||||
about: "परिचय",
|
||||
},
|
||||
general: {
|
||||
title: "सामान्य",
|
||||
description: "Unsloth के लिए वैश्विक प्राथमिकताएं।",
|
||||
account: "खाता",
|
||||
huggingFaceToken: "Hugging Face टोकन",
|
||||
huggingFaceTokenDescription:
|
||||
"गेटेड मॉडल लोड करने और आर्टिफैक्ट पुश करने के लिए उपयोग किया जाता है।",
|
||||
hideToken: "token छिपाएं",
|
||||
showToken: "token दिखाएं",
|
||||
tokenSaved: "Token सहेजा गया",
|
||||
password: "पासवर्ड",
|
||||
passwordDescription: "इस Studio खाते के लिए पासवर्ड बदलें।",
|
||||
passwordDialog: {
|
||||
trigger: "पासवर्ड बदलें",
|
||||
title: "पासवर्ड बदलें",
|
||||
description:
|
||||
"अपना वर्तमान पासवर्ड दर्ज करें और एक नया चुनें (कम से कम {minLength} अक्षर)।",
|
||||
currentPassword: "वर्तमान पासवर्ड",
|
||||
newPassword: "नया पासवर्ड",
|
||||
confirmPassword: "नए पासवर्ड की पुष्टि करें",
|
||||
currentTooShort:
|
||||
"वर्तमान पासवर्ड कम से कम {minLength} अक्षरों का होना चाहिए।",
|
||||
newTooShort: "नया पासवर्ड कम से कम {minLength} अक्षरों का होना चाहिए।",
|
||||
mismatch: "पासवर्ड मेल नहीं खाते।",
|
||||
samePassword:
|
||||
"नया पासवर्ड आपके वर्तमान पासवर्ड से अलग होना चाहिए।",
|
||||
update: "पासवर्ड अपडेट करें",
|
||||
updating: "अपडेट हो रहा है...",
|
||||
updated: "पासवर्ड अपडेट हो गया।",
|
||||
updateFailed: "पासवर्ड अपडेट विफल रहा।",
|
||||
},
|
||||
chatDefaults: "चैट डिफ़ॉल्ट",
|
||||
autoTitleNewChats: "नई चैट को स्वतः शीर्षक दें",
|
||||
autoTitleNewChatsDescription:
|
||||
"पहले संदेश से एक छोटा शीर्षक बनाएं।",
|
||||
helperLlm: {
|
||||
sectionTitle: "Helper LLM",
|
||||
preloadOnStartup: "स्टार्टअप पर Helper LLM को प्री-कैश करें",
|
||||
preloadOnStartupDescription:
|
||||
"स्टार्टअप पर AI Assist हेल्पर मॉडल को पृष्ठभूमि में डाउनलोड करें। डिफ़ॉल्ट रूप से बंद; AI Assist अभी भी इसे मांग पर प्राप्त कर सकता है।",
|
||||
disabledByEnv:
|
||||
"बैकएंड एनवायरनमेंट में UNSLOTH_HELPER_MODEL_DISABLE द्वारा अक्षम।",
|
||||
loadError: "Helper LLM सेटिंग्स लोड करने में विफल।",
|
||||
saveError: "Helper LLM सेटिंग्स सहेजने में विफल।",
|
||||
},
|
||||
modelAutoSwitch: {
|
||||
sectionTitle: "मॉडल ऑटो-स्विच (OpenAI API)",
|
||||
enable: "अनुरोध के अनुसार मॉडल बदलें",
|
||||
enableDescription:
|
||||
"जब कोई OpenAI-संगत अनुरोध किसी अन्य डाउनलोड किए गए GGUF का नाम लेता है, तो सर्व करने से पहले उसे लोड करें। डिफ़ॉल्ट रूप से बंद; अज्ञात नाम लोड किए गए मॉडल को सर्व करते रहते हैं।",
|
||||
idleUnload: "निष्क्रिय ऑटो-अनलोड",
|
||||
idleUnloadDescription:
|
||||
"VRAM मुक्त करने के लिए इतने निष्क्रिय सेकंड के बाद मॉडल को अनलोड करें; अगला अनुरोध इसे फिर से लोड करता है। 0 इसे लोड रखता है।",
|
||||
idleNeedsEnable:
|
||||
"अनुरोध के अनुसार मॉडल बदलें चालू करें ताकि अनलोड किया गया मॉडल अगले उपयोग पर फिर से लोड हो।",
|
||||
idleActiveViaEnv:
|
||||
"निष्क्रिय ऑटो-अनलोड UNSLOTH_MODEL_IDLE_TTL एनवायरनमेंट वेरिएबल के माध्यम से सक्रिय है।",
|
||||
loadError: "मॉडल ऑटो-स्विच सेटिंग्स लोड करने में विफल।",
|
||||
saveError: "मॉडल ऑटो-स्विच सेटिंग्स सहेजने में विफल।",
|
||||
idleError: "सेकंड की पूरी संख्या दर्ज करें (0 या अधिक)।",
|
||||
},
|
||||
previewSharing: {
|
||||
sectionTitle: "पूर्वावलोकन साझाकरण",
|
||||
enableLabel: "सार्वजनिक पूर्वावलोकन लिंक",
|
||||
enableDescription:
|
||||
"किसी भी हस्ताक्षरित लिंक वाले व्यक्ति को बिना लॉगिन के तैयार मॉडल से चैट करने दें। सार्वजनिक पूर्वावलोकन सतह को ऑफ़लाइन करने के लिए बंद करें; साझा किए गए लिंक काम करना बंद कर देते हैं।",
|
||||
loadError: "पूर्वावलोकन साझाकरण सेटिंग्स लोड करने में विफल।",
|
||||
saveError: "पूर्वावलोकन साझाकरण सेटिंग्स सहेजने में विफल।",
|
||||
revokeLabel: "सभी पूर्वावलोकन लिंक रद्द करें",
|
||||
revokeDescription:
|
||||
"हस्ताक्षर करने वाले सीक्रेट को घुमाएं ताकि आपके द्वारा साझा किया गया हर लिंक काम करना बंद कर दे। नए कॉपी किए गए लिंक काम करते रहते हैं।",
|
||||
revokeAction: "लिंक रद्द करें",
|
||||
revoking: "रद्द किया जा रहा है...",
|
||||
revokeConfirmTitle: "सभी पूर्वावलोकन लिंक रद्द करें?",
|
||||
revokeConfirmDescription:
|
||||
"आपके द्वारा साझा किया गया हर पूर्वावलोकन लिंक तुरंत काम करना बंद कर देगा। इसे पूर्ववत नहीं किया जा सकता।",
|
||||
revokeConfirmAction: "सभी लिंक रद्द करें",
|
||||
revoked: "सभी पूर्वावलोकन लिंक रद्द किए गए",
|
||||
revokeError: "पूर्वावलोकन लिंक रद्द नहीं किए जा सके",
|
||||
},
|
||||
notifications: {
|
||||
sectionTitle: "सूचनाएं",
|
||||
showLlamaUpdates: "llama.cpp अपडेट सूचनाएं",
|
||||
showLlamaUpdatesDescription:
|
||||
"नए मॉडल चलाने के लिए जब कोई नया llama.cpp बिल्ड उपलब्ध हो तो सूचित करें। यदि आप केवल ट्रेन करते हैं तो बंद कर दें।",
|
||||
},
|
||||
gettingStarted: "शुरुआत करें",
|
||||
startOnboarding: "ऑनबोर्डिंग शुरू करें",
|
||||
startOnboardingDescription:
|
||||
"अपना खाता बदले बिना सेटअप विज़ार्ड फिर से खोलें।",
|
||||
startOnboardingAction: "ऑनबोर्डिंग शुरू करें",
|
||||
uploads: {
|
||||
sectionTitle: "अपलोड",
|
||||
maxUploadSize: "ट्रेनिंग डेटासेट अपलोड सीमा",
|
||||
maxUploadSizeDescription: "डिफ़ॉल्ट {defaultSize} MB है।",
|
||||
},
|
||||
rag: {
|
||||
sectionTitle: "दस्तावेज़ और RAG",
|
||||
embeddingModel: "एम्बेडिंग मॉडल",
|
||||
embeddingModelDescription:
|
||||
"आपके दस्तावेज़ों को इंडेक्स और खोजने के लिए उपयोग किया जाने वाला Hugging Face मॉडल या स्थानीय पथ। डिफ़ॉल्ट {defaultModel} है।",
|
||||
reindexWarning:
|
||||
"केवल नए इंडेक्स किए गए दस्तावेज़ों को प्रभावित करता है। मॉडल बदलने के बाद मौजूदा दस्तावेज़ फिर से अपलोड करें।",
|
||||
emptyError: "एक Hugging Face मॉडल id या स्थानीय पथ दर्ज करें।",
|
||||
loadError: "एम्बेडिंग मॉडल सेटिंग लोड करने में विफल।",
|
||||
saveError: "एम्बेडिंग मॉडल सहेजने में विफल।",
|
||||
saved: "एम्बेडिंग मॉडल सहेजा गया।",
|
||||
saveAnyway: "फिर भी सहेजें",
|
||||
resetAction: "डिफ़ॉल्ट पर रीसेट करें",
|
||||
},
|
||||
storage: {
|
||||
sectionTitle: "स्टोरेज",
|
||||
modelsFolder: "मॉडल फ़ोल्डर",
|
||||
modelsFolderDescription: "जहां डाउनलोड किए गए मॉडल संग्रहीत होते हैं।",
|
||||
openAction: "खोलें",
|
||||
copyAction: "पथ कॉपी करें",
|
||||
copied: "पथ कॉपी किया गया",
|
||||
openError: "फ़ोल्डर नहीं खोला जा सका",
|
||||
copyError: "पथ कॉपी नहीं किया जा सका",
|
||||
},
|
||||
resetPreferences: {
|
||||
sectionTitle: "खतरनाक क्षेत्र",
|
||||
label: "सभी स्थानीय प्राथमिकताएं रीसेट करें",
|
||||
description:
|
||||
"केवल-स्थानीय प्राथमिकताएं साफ़ करता है। चैट, API एक्सेस, और DB-समर्थित सेटिंग्स बनी रहती हैं।",
|
||||
action: "प्राथमिकताएं रीसेट करें",
|
||||
confirmTitle: "सभी स्थानीय प्राथमिकताएं रीसेट करें?",
|
||||
confirmDescription:
|
||||
"केवल-स्थानीय प्राथमिकताएं साफ़ करता है और Unsloth को फिर से लोड करता है। चैट, API एक्सेस, और DB-समर्थित सेटिंग्स बनी रहती हैं।",
|
||||
confirmAction: "रीसेट करें और फिर से लोड करें",
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
title: "प्रोफ़ाइल",
|
||||
description: "Unsloth में आपकी प्रोफ़ाइल कैसे दिखती है।",
|
||||
changePicture: "प्रोफ़ाइल चित्र बदलें",
|
||||
displayName: "प्रदर्शन नाम",
|
||||
nickname: "Unsloth आपको क्या कहकर बुलाए?",
|
||||
nicknamePlaceholder: "उपनाम",
|
||||
nicknameSaved: "पसंदीदा नाम सहेजा गया",
|
||||
avatarShape: "प्रोफ़ाइल चित्र आकार",
|
||||
avatarShapeCircle: "वृत्त",
|
||||
avatarShapeRounded: "गोल किनारे",
|
||||
chooseSloth: "या एक sloth चुनें",
|
||||
nameSaved: "प्रोफ़ाइल नाम सहेजा गया",
|
||||
namePersistErrorTitle: "प्रोफ़ाइल नाम सहेजा नहीं जा सका",
|
||||
namePersistErrorDescription:
|
||||
"इस सत्र के लिए नाम अपडेट किया गया, लेकिन फिर से लोड करने के बाद शायद न रहे।",
|
||||
photoUpdated: "प्रोफ़ाइल फोटो अपडेट हुई",
|
||||
photoPersistErrorTitle: "प्रोफ़ाइल फोटो सहेजी नहीं जा सकी",
|
||||
photoPersistErrorDescription:
|
||||
"इस सत्र के लिए फोटो अपडेट की गई, लेकिन फिर से लोड करने के बाद शायद न रहे।",
|
||||
photoUpdateErrorTitle: "प्रोफ़ाइल फोटो अपडेट नहीं की जा सकी",
|
||||
imageUseError: "इस छवि का उपयोग नहीं किया जा सका।",
|
||||
},
|
||||
appearance: {
|
||||
title: "रूप-रंग",
|
||||
description: "इस डिवाइस पर Unsloth Studio कैसा दिखता है।",
|
||||
theme: {
|
||||
title: "थीम",
|
||||
label: "रंग योजना",
|
||||
description: "लाइट, डार्क, या अपने सिस्टम का अनुसरण करें।",
|
||||
system: "सिस्टम",
|
||||
light: "लाइट",
|
||||
dark: "डार्क",
|
||||
},
|
||||
language: {
|
||||
title: "भाषा",
|
||||
label: "प्रदर्शन भाषा",
|
||||
description: "Unsloth द्वारा उपयोग की जाने वाली भाषा।",
|
||||
autoDetect: "स्वतः पहचान",
|
||||
},
|
||||
layout: {
|
||||
title: "लेआउट",
|
||||
compactSidebar: "साइडबार को डिफ़ॉल्ट रूप से पिन करें",
|
||||
compactSidebarDescription:
|
||||
"साइडबार को आइकन में संक्षिप्त करने के बजाय विस्तारित रखें।",
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
title: "सिस्टम",
|
||||
description: "इस Studio सर्वर के हार्डवेयर और स्टोरेज की निगरानी करें।",
|
||||
liveUpdates: "लाइव अपडेट",
|
||||
floatingWindow: "फ्लोटिंग विंडो",
|
||||
disableOverlay: "ओवरले अक्षम करें",
|
||||
liveMonitor: {
|
||||
title: "लाइव मॉनिटर",
|
||||
cpu: "CPU",
|
||||
ram: "RAM",
|
||||
disk: "डिस्क",
|
||||
vram: "VRAM",
|
||||
cpuCores: "{logical} लॉजिकल / {physical} फिजिकल कोर",
|
||||
currentLoad: "वर्तमान लोड",
|
||||
free: "{value} खाली",
|
||||
noGpu: "कोई दृश्यमान GPU नहीं",
|
||||
},
|
||||
gpu: {
|
||||
title: "GPU डिवाइस",
|
||||
noGpu: "कोई दृश्यमान GPU नहीं मिला। केवल-CPU संसाधन ऊपर दिखाए गए हैं।",
|
||||
unknownDevice: "अज्ञात GPU",
|
||||
deviceWithIndex: "GPU {index}",
|
||||
vramUtilization: "VRAM",
|
||||
used: "{value} उपयोग में",
|
||||
free: "{value} खाली",
|
||||
total: "{value} कुल",
|
||||
},
|
||||
storage: {
|
||||
title: "स्टोरेज",
|
||||
systemDisk: "सिस्टम डिस्क",
|
||||
diskUsage: "{used} उपयोग में / {total}",
|
||||
diskFree: "{free} खाली",
|
||||
modelsFolder: "मॉडल फ़ोल्डर",
|
||||
modelsFolderDescription: "जहां डाउनलोड किए गए मॉडल संग्रहीत होते हैं।",
|
||||
openAction: "खोलें",
|
||||
copyAction: "पथ कॉपी करें",
|
||||
copied: "पथ कॉपी किया गया",
|
||||
openError: "फ़ोल्डर नहीं खोला जा सका",
|
||||
copyError: "पथ कॉपी नहीं किया जा सका",
|
||||
},
|
||||
environment: {
|
||||
title: "एनवायरनमेंट",
|
||||
backend: "बैकएंड",
|
||||
python: "Python",
|
||||
torch: "Torch",
|
||||
transformers: "Transformers",
|
||||
uptime: "अपटाइम",
|
||||
processMemory: "प्रोसेस मेमोरी",
|
||||
notInstalled: "इंस्टॉल नहीं है",
|
||||
unknown: "अज्ञात",
|
||||
},
|
||||
},
|
||||
chat: {
|
||||
title: "चैट",
|
||||
description: "इस डिवाइस पर संग्रहीत चैट इतिहास प्रबंधित करें।",
|
||||
modelDisclaimer: "मॉडल अस्वीकरण दिखाएं",
|
||||
modelDisclaimerDescription:
|
||||
'चैट बॉक्स के नीचे "LLMs can make mistakes" दिखाएं।',
|
||||
artifacts: {
|
||||
title: "Canvas",
|
||||
collapseHtmlBlocks: "HTML ब्लॉक संक्षिप्त करें",
|
||||
collapseHtmlBlocksDescription:
|
||||
"Canvas मोड स्वतः पूर्ण HTML को संक्षिप्त कर देता है। Canvas बंद होने पर फेंस्ड HTML दस्तावेज़ों को भी संक्षिप्त करने के लिए इसे चालू करें।",
|
||||
allowNetworkAccess: "canvas नेटवर्क एक्सेस की अनुमति दें",
|
||||
allowNetworkAccessDescription:
|
||||
"canvas पूर्वावलोकन को CDN से स्क्रिप्ट, स्टाइल, फ़ॉन्ट, मीडिया, और नेटवर्क संसाधन लोड करने दें। पूरी तरह ऑफ़लाइन पूर्वावलोकन के लिए बंद रखें।",
|
||||
},
|
||||
data: "डेटा",
|
||||
exportHistory: "चैट इतिहास एक्सपोर्ट करें",
|
||||
exportHistoryDescription: "सभी चैट और संदेशों को JSON के रूप में डाउनलोड करें।",
|
||||
exportAction: "एक्सपोर्ट करें",
|
||||
exportingAction: "एक्सपोर्ट हो रहा है...",
|
||||
exportConversations: "हाल के और Projects एक्सपोर्ट करें",
|
||||
exportConversationsDescription:
|
||||
"हाल के या हाल के के साथ प्रोजेक्ट चैट को Raw JSONL, CSV, या ShareGPT JSONL के रूप में, संयुक्त या प्रति चैट डाउनलोड करें।",
|
||||
exportConversationsAction: "एक्सपोर्ट करें",
|
||||
exportScopeRecents: "हाल के",
|
||||
exportScopeAll: "हाल के + Projects",
|
||||
exportCombinedSuffix: "(संयुक्त)",
|
||||
exportPerChatSuffix: "(प्रति चैट)",
|
||||
importChats: "चैट इंपोर्ट करें",
|
||||
importChatsDescription:
|
||||
"एक JSONL, NDJSON, या CSV एक्सपोर्ट को हाल के में इंपोर्ट करें।",
|
||||
importChatsAction: "इंपोर्ट करें",
|
||||
importNoConversations: "फ़ाइल में कोई वार्तालाप नहीं मिला।",
|
||||
importedOneChat: "1 वार्तालाप हाल के में इंपोर्ट किया गया।",
|
||||
importedChatCount: "{count} वार्तालाप हाल के में इंपोर्ट किए गए।",
|
||||
importFailed: "इंपोर्ट विफल रहा।",
|
||||
clearHistory: "चैट इतिहास साफ़ करें",
|
||||
clearHistoryDescription: "इस डिवाइस से चैट इतिहास हटाएं।",
|
||||
clearAction: "साफ़ करें",
|
||||
clearAllChats: "सभी चैट साफ़ करें",
|
||||
clearAllChatsDescription: "इस डिवाइस पर हर चैट को स्थायी रूप से हटाएं।",
|
||||
noChatsToClear: "साफ़ करने के लिए कोई चैट नहीं।",
|
||||
clearOneChatDescription:
|
||||
"इस डिवाइस पर एकमात्र चैट को स्थायी रूप से हटाएं।",
|
||||
clearChatCountDescription:
|
||||
"इस डिवाइस पर सभी {count} चैट को स्थायी रूप से हटाएं।",
|
||||
clearChatsAction: "चैट साफ़ करें",
|
||||
clearOneChatTitle: "1 चैट साफ़ करें?",
|
||||
clearChatsTitle: "{count} चैट साफ़ करें?",
|
||||
clearChatsConfirmDescription:
|
||||
"इस डिवाइस पर हर चैट को स्थायी रूप से हटा देता है। इसे पूर्ववत नहीं किया जा सकता।",
|
||||
clearingAction: "साफ़ किया जा रहा है...",
|
||||
clearOneChatAction: "1 चैट साफ़ करें",
|
||||
clearChatCountAction: "{count} चैट साफ़ करें",
|
||||
clearedAllChats: "सभी चैट साफ़ की गईं",
|
||||
clearedOneChat: "1 चैट साफ़ की गई",
|
||||
clearedChatCount: "{count} चैट साफ़ की गईं",
|
||||
someChatsCouldNotBeCleared: "कुछ चैट साफ़ नहीं की जा सकीं",
|
||||
chatsClearedRemainOne:
|
||||
"{clearedCount} चैट साफ़ की गईं; 1 चैट शेष है। कृपया पुनः प्रयास करें।",
|
||||
chatsClearedRemain:
|
||||
"{clearedCount} चैट साफ़ की गईं; {remainingCount} चैट शेष हैं। कृपया पुनः प्रयास करें।",
|
||||
oneChatClearedRemain:
|
||||
"1 चैट साफ़ की गई; {remainingCount} चैट शेष हैं। कृपया पुनः प्रयास करें।",
|
||||
oneChatClearedRemainOne: "1 चैट साफ़ की गई; 1 चैट शेष है। कृपया पुनः प्रयास करें।",
|
||||
storageClearFailedOne:
|
||||
"एक स्टोरेज साफ़ करना विफल रहा; 1 चैट शेष रह सकती है। कृपया पुनः प्रयास करें।",
|
||||
storageClearFailed:
|
||||
"एक स्टोरेज साफ़ करना विफल रहा; {count} चैट शेष रह सकती हैं। कृपया पुनः प्रयास करें।",
|
||||
failedToClearChats: "चैट साफ़ करने में विफल",
|
||||
},
|
||||
connections: {
|
||||
title: "कनेक्शन",
|
||||
description: "प्रदाता और बाहरी कनेक्शन प्रबंधित करें।",
|
||||
},
|
||||
apiKeys: {
|
||||
title: "API",
|
||||
description: "OpenAI-संगत API के माध्यम से Unsloth तक पहुंचें।",
|
||||
readDocs: "API दस्तावेज़ पढ़ें",
|
||||
noAccess: "अभी तक कोई API एक्सेस नहीं।",
|
||||
accessTokens: "एक्सेस token",
|
||||
loadError: "API एक्सेस लोड नहीं किया जा सका।",
|
||||
createError: "एक्सेस token नहीं बनाया जा सका।",
|
||||
revokeError: "एक्सेस token रद्द नहीं किया जा सका।",
|
||||
never: "कभी नहीं",
|
||||
tokenNamePlaceholder: "Token नाम (उदा. production)",
|
||||
newAccessTokenName: "नया एक्सेस token नाम",
|
||||
createToken: "token बनाएं",
|
||||
creating: "बनाया जा रहा है...",
|
||||
newTokenCreated: "नया एक्सेस token बनाया गया",
|
||||
accessTokenCopied: "एक्सेस token कॉपी किया गया",
|
||||
copyAccessToken: "एक्सेस token कॉपी करें",
|
||||
copyNow: "अभी कॉपी करें - यह फिर से नहीं दिखाया जाएगा।",
|
||||
usageExamples: "उपयोग उदाहरण",
|
||||
usageTools: "टूल",
|
||||
exampleCurlTools: "curl + टूल",
|
||||
examplePythonTools: "Python + टूल",
|
||||
exampleJavaScriptTools: "JavaScript + टूल",
|
||||
exampleCurlAdvanced: "curl + उन्नत",
|
||||
examplePythonAdvanced: "Python + उन्नत",
|
||||
exampleJavaScriptAdvanced: "JavaScript + उन्नत",
|
||||
osUnix: "Linux / macOS / WSL",
|
||||
osWindows: "Windows",
|
||||
secureHttps: "सुरक्षित HTTPS",
|
||||
secureHttpsHint:
|
||||
"0.0.0.0 पोर्ट अभी भी विश्व स्तर पर पहुंच योग्य है। पूर्ण सुरक्षा के लिए, केवल इस HTTPS लिंक को उजागर करने के लिए Unsloth Studio को --secure के साथ लॉन्च करें।",
|
||||
copyTunnelUrl: "टनल URL कॉपी करें",
|
||||
copySnippet: "स्निपेट कॉपी करें",
|
||||
copy: "कॉपी करें",
|
||||
copied: "कॉपी किया गया",
|
||||
setupDocs: "सेटअप दस्तावेज़:",
|
||||
codingAgents: "कोडिंग एजेंट",
|
||||
codingAgentsHint:
|
||||
"इस सर्वर के विरुद्ध एक कोडिंग एजेंट लॉन्च करें। यह लोड किए गए मॉडल का उपयोग करता है; एक स्थानीय सर्वर स्वचालित रूप से API key बनाता है, एक रिमोट सर्वर इसे कमांड में शामिल करता है।",
|
||||
codingAgentsSwap: "claude को codex, openclaw, opencode, hermes, या pi से बदलें।",
|
||||
codingAgentDetected: "इस मशीन पर इंस्टॉल है",
|
||||
codingAgentsDetectedHint: "इस मशीन पर पाया गया: {agents}।",
|
||||
relativeNever: "कभी नहीं",
|
||||
relativeJustNow: "अभी",
|
||||
relativeHoursAgo: "{count} घंटे पहले",
|
||||
relativeDaysAgo: "{count} दिन पहले",
|
||||
relativeMonthsAgo: "{count} माह पहले",
|
||||
relativeYearsAgo: "{count} वर्ष पहले",
|
||||
expired: "समाप्त",
|
||||
today: "आज",
|
||||
inDays: "{count} दिन में",
|
||||
created: "बनाया गया {value}",
|
||||
used: "उपयोग किया गया {value}",
|
||||
expires: "समाप्त होता है {value}",
|
||||
actionsFor: "{name} के लिए कार्रवाइयां",
|
||||
copyPrefix: "प्रीफ़िक्स कॉपी करें",
|
||||
revokeToken: "token रद्द करें",
|
||||
revokeTitle: 'एक्सेस token "{name}" रद्द करें?',
|
||||
revokeDescription:
|
||||
"इस token का उपयोग करने वाले ऐप तुरंत एक्सेस खो देते हैं। इसे पूर्ववत नहीं किया जा सकता।",
|
||||
revokeAction: '"{name}" रद्द करें',
|
||||
revoking: "रद्द किया जा रहा है...",
|
||||
},
|
||||
about: {
|
||||
title: "परिचय",
|
||||
description: "दस्तावेज़, रिलीज़ नोट्स, प्रतिक्रिया, और बिल्ड जानकारी।",
|
||||
studioVersion: "Unsloth संस्करण",
|
||||
packageVersion: "पैकेज संस्करण",
|
||||
llamaCppVersion: "llama.cpp संस्करण",
|
||||
hardware: "हार्डवेयर",
|
||||
gpu: "GPU",
|
||||
cuda: "CUDA",
|
||||
rocm: "ROCm",
|
||||
updates: "अपडेट",
|
||||
help: "सहायता",
|
||||
documentation: "दस्तावेज़",
|
||||
releaseNotes: "रिलीज़ नोट्स",
|
||||
whatsNew: "नया क्या है",
|
||||
feedback: "प्रतिक्रिया",
|
||||
reportIssue: "समस्या रिपोर्ट करें",
|
||||
license: {
|
||||
sectionTitle: "लाइसेंस",
|
||||
studioLabel: "Unsloth Studio",
|
||||
studioLicense: "AGPL-3.0",
|
||||
studioDescription: "GNU AGPL v3.0 के तहत ओपन सोर्स।",
|
||||
libraryLabel: "Unsloth Core",
|
||||
libraryLicense: "Apache-2.0",
|
||||
libraryDescription: "Apache 2.0 के तहत लाइसेंस प्राप्त।",
|
||||
},
|
||||
dangerZone: "खतरनाक क्षेत्र",
|
||||
shutDownStudio: "Unsloth Studio शट डाउन करें",
|
||||
shutDownStudioDescription:
|
||||
"Unsloth सर्वर को रोकता है और आपके सत्र को समाप्त करता है।",
|
||||
shutDown: "शट डाउन करें",
|
||||
update: {
|
||||
title: "Unsloth Studio अपडेट करें",
|
||||
commandText: "{label} टेक्स्ट",
|
||||
copied: "कॉपी किया गया",
|
||||
copyCommand: "कमांड कॉपी करें",
|
||||
commandCopied: "{label} कॉपी किया गया",
|
||||
copyNamedCommand: "{label} कॉपी करें",
|
||||
checkingInstall: "जांच रहे हैं कि Unsloth कैसे इंस्टॉल किया गया था...",
|
||||
installIntro: "Unsloth इंस्टॉल या अपडेट करने के लिए:",
|
||||
localUpdateHeading: "स्थानीय अपडेट",
|
||||
installCommandUnix: "macOS/Linux इंस्टॉल कमांड",
|
||||
installCommandWindows: "Windows इंस्टॉल कमांड",
|
||||
localInstallDetected:
|
||||
"स्थानीय इंस्टॉल का पता चला। इसे PyPI से बदलने से बचने के लिए अपने मूल checkout से अपडेट करें।",
|
||||
pullThenUpdate:
|
||||
"नवीनतम परिवर्तन खींचें, फिर स्थानीय इंस्टॉलर चलाएं:",
|
||||
gitPullCommand: "git pull कमांड",
|
||||
localInstallerCommand: "स्थानीय इंस्टॉलर कमांड",
|
||||
sourceInstallDetected:
|
||||
"सोर्स या VCS पैकेज इंस्टॉल का पता चला। मूल स्थानीय पथ या Git URL से पुनः इंस्टॉल करें।",
|
||||
repoCheckoutFallback:
|
||||
"यदि आपके पास अभी भी रेपो checkout है, तो उससे स्थानीय इंस्टॉलर चलाएं:",
|
||||
restartAfterUpdate: "अपडेट करने के बाद Unsloth को पुनः आरंभ करें।",
|
||||
desktopManaged:
|
||||
"डेस्कटॉप ऐप अपने बंडल किए गए बैकएंड को अपडेट रखता है और नया संस्करण उपलब्ध होने पर संकेत देगा।",
|
||||
unknownInstall:
|
||||
"यह पता नहीं लगाया जा सका कि Unsloth कैसे इंस्टॉल किया गया था। इंस्टॉलर या PyPI इंस्टॉल के लिए, ऊपर दिए गए कमांड का उपयोग करें।",
|
||||
localCheckout:
|
||||
"स्थानीय checkout इंस्टॉल के लिए, उस checkout से स्थानीय इंस्टॉलर चलाएं:",
|
||||
docs: "इंस्टॉल दस्तावेज़:",
|
||||
docsInstall: "इंस्टॉलेशन",
|
||||
docsUpdating: "अपडेट करना",
|
||||
docsMac: "Mac",
|
||||
docsWindows: "Windows",
|
||||
},
|
||||
},
|
||||
},
|
||||
studio: {
|
||||
routeTitle: "ट्रेनिंग",
|
||||
title: "फ़ाइन-ट्यूनिंग Studio",
|
||||
subtitles: {
|
||||
configure: "कॉन्फ़िगर करें और ट्रेनिंग शुरू करें",
|
||||
trainingInProgress: "ट्रेनिंग जारी है",
|
||||
viewPastRuns: "पिछली ट्रेनिंग रन देखें",
|
||||
viewingPastRun: "पिछली रन देख रहे हैं",
|
||||
},
|
||||
tabs: {
|
||||
configure: "कॉन्फ़िगर करें",
|
||||
currentRun: "वर्तमान रन",
|
||||
history: "इतिहास",
|
||||
},
|
||||
loadingRuntime: "ट्रेनिंग रनटाइम लोड हो रहा है...",
|
||||
backToHistory: "इतिहास पर वापस जाएं",
|
||||
sections: {
|
||||
model: "मॉडल",
|
||||
dataset: "डेटासेट",
|
||||
params: "पैरामीटर",
|
||||
training: "ट्रेनिंग",
|
||||
charts: "चार्ट",
|
||||
progress: "ट्रेनिंग प्रगति",
|
||||
},
|
||||
configure: {
|
||||
title: "कॉन्फ़िगर करें",
|
||||
description: "एक मॉडल, डेटासेट, और ट्रेनिंग सेटिंग्स चुनें।",
|
||||
startTraining: "ट्रेनिंग शुरू करें",
|
||||
starting: "शुरू हो रहा है...",
|
||||
loadingModel: "मॉडल लोड हो रहा है...",
|
||||
checkingDataset: "डेटासेट जांचा जा रहा है...",
|
||||
trainingConfig: "ट्रेनिंग कॉन्फ़िग",
|
||||
},
|
||||
model: {
|
||||
title: "मॉडल",
|
||||
description: "बेस मॉडल और ट्रेनिंग विधि चुनें",
|
||||
fasterTrainingBadge: "2x तेज़ ट्रेनिंग",
|
||||
baseModel: "बेस मॉडल",
|
||||
localModel: "स्थानीय मॉडल",
|
||||
localModelTooltip:
|
||||
"स्थानीय रूप से डाउनलोड किए गए मॉडल या कस्टम HF रेपो का पथ।",
|
||||
scanningLocalAndCachedModels: "स्थानीय और कैश किए गए मॉडल स्कैन हो रहे हैं...",
|
||||
scanning: "स्कैन हो रहा है...",
|
||||
scanningLocalModels: "स्थानीय मॉडल स्कैन हो रहे हैं...",
|
||||
noLocalModelsFound: "कोई स्थानीय मॉडल नहीं मिला",
|
||||
noLocalModelsFoundManual: "कोई स्थानीय मॉडल नहीं मिला। पथ मैन्युअल रूप से दर्ज करें।",
|
||||
failedToLoadLocalModels: "स्थानीय मॉडल लोड करने में विफल",
|
||||
hfCache: "HF कैश",
|
||||
customFolders: "कस्टम फ़ोल्डर",
|
||||
localDir: "स्थानीय dir",
|
||||
huggingFaceModel: "Hugging Face मॉडल",
|
||||
huggingFaceModelTooltip:
|
||||
"Hugging Face मॉडल खोजें या हमारी अनुशंसित सूची से चुनें।",
|
||||
searchModels: "मॉडल खोजें...",
|
||||
searching: "खोजा जा रहा है...",
|
||||
noModelsFound: "कोई मॉडल नहीं मिला",
|
||||
needsVram: "~{vram}GB VRAM चाहिए (GPU: {gpu}GB)",
|
||||
tightVram: "~{vram}GB VRAM ({gpu}GB पर बमुश्किल फिट)",
|
||||
vramEstimate: "लगभग {vram}GB VRAM",
|
||||
method: "विधि",
|
||||
methodTooltip:
|
||||
"QLoRA सबसे कम VRAM के लिए 4-बिट क्वांटाइज़ेशन का उपयोग करता है। LoRA 16-बिट का उपयोग करता है। Full सभी वेट्स को अपडेट करता है। CPT (Continued Pretraining) चैट फ़ॉर्मेटिंग के बिना मॉडल को नए डोमेन के अनुकूल बनाने के लिए कच्चे टेक्स्ट पर ट्रेन करता है।",
|
||||
readMore: "और पढ़ें",
|
||||
fullFineTune: "फुल फ़ाइन-ट्यून",
|
||||
checkingToken: "token जांचा जा रहा है...",
|
||||
getOrUpdateToken: "token प्राप्त या अपडेट करें",
|
||||
huggingFaceTokenOptional: "Hugging Face Token (वैकल्पिक)",
|
||||
continuedPretraining: "निरंतर प्री-ट्रेनिंग",
|
||||
localModels: "स्थानीय मॉडल",
|
||||
localModelsFound: "{count} स्थानीय/कैश किए गए मॉडल मिले",
|
||||
loadingLocalModels: "स्थानीय मॉडल लोड हो रहे हैं...",
|
||||
},
|
||||
dataset: {
|
||||
title: "डेटासेट",
|
||||
description: "ट्रेनिंग डेटा चुनें या अपलोड करें",
|
||||
source: "डेटासेट स्रोत",
|
||||
chooseDataset: "डेटासेट चुनें",
|
||||
chooseDatasetTooltip:
|
||||
"Hugging Face और स्थानीय recipe आउटपुट के बीच स्विच करने के लिए पॉपअप टैब का उपयोग करें।",
|
||||
localTab: "स्थानीय",
|
||||
searchHuggingFaceDatasets: "Hugging Face डेटासेट खोजें...",
|
||||
searchLocalDatasets: "स्थानीय डेटासेट खोजें...",
|
||||
searching: "खोजा जा रहा है...",
|
||||
noDatasetsFound: "कोई डेटासेट नहीं मिला",
|
||||
loadingLocalDatasets: "स्थानीय डेटासेट लोड हो रहे हैं...",
|
||||
failedToLoadLocalDatasets: "स्थानीय डेटासेट लोड करने में विफल।",
|
||||
noLocalDatasetsYet: "अभी तक कोई स्थानीय डेटासेट नहीं।",
|
||||
noLocalDatasetsMatchSearch: "कोई स्थानीय डेटासेट खोज से मेल नहीं खाता।",
|
||||
openDataRecipes: "Data Recipes खोलें",
|
||||
browsingSource: "{browsing} ब्राउज़ कर रहे हैं। वर्तमान चयन {current} रहता है।",
|
||||
localDatasets: "स्थानीय डेटासेट",
|
||||
localDataset: "स्थानीय डेटासेट",
|
||||
localDatasetRows: " / {count} पंक्तियां",
|
||||
huggingFaceDataset: "Hugging Face डेटासेट",
|
||||
localDatasetMetadata: "स्थानीय डेटासेट मेटाडेटा",
|
||||
dataRecipeOutput: "Data Recipe आउटपुट।",
|
||||
rows: "पंक्तियां",
|
||||
columns: "कॉलम",
|
||||
batches: "बैच",
|
||||
updated: "अपडेट किया गया",
|
||||
evalDataset: "Eval डेटासेट",
|
||||
uploading: "अपलोड हो रहा है...",
|
||||
upload: "अपलोड करें",
|
||||
uploadEvalFile: "eval फ़ाइल अपलोड करें",
|
||||
evalDatasetDescription:
|
||||
"वैकल्पिक। यदि प्रदान नहीं किया गया, तो ट्रेनिंग डेटा से एक छोटा हिस्सा अलग किया जाएगा।",
|
||||
advanced: "उन्नत",
|
||||
targetFormat: "लक्ष्य प्रारूप",
|
||||
targetFormatTooltip:
|
||||
"आपके ट्रेनिंग डेटा का प्रारूप। ऑटो-डिटेक्ट अधिकांश डेटासेट के लिए काम करता है।",
|
||||
auto: "स्वतः",
|
||||
rawText: "कच्चा टेक्स्ट",
|
||||
trainSplitStart: "ट्रेन स्प्लिट प्रारंभ",
|
||||
trainSplitStartTooltip:
|
||||
"एक प्रारंभ पंक्ति इंडेक्स (समावेशी, 0-आधारित) निर्दिष्ट करके केवल अपने ट्रेनिंग स्प्लिट के उपसमूह पर ट्रेन करें। पहली पंक्ति से शुरू करने के लिए खाली छोड़ें।",
|
||||
trainSplitEnd: "ट्रेन स्प्लिट समाप्त",
|
||||
trainSplitEndTooltip:
|
||||
"ट्रेनिंग स्प्लिट से शामिल करने के लिए अंतिम पंक्ति इंडेक्स (समावेशी, 0-आधारित)। उदाहरण के लिए, पहली 100 पंक्तियों पर ट्रेन करने के लिए प्रारंभ को 0 और समाप्त को 99 सेट करें। सभी शेष पंक्तियों का उपयोग करने के लिए खाली छोड़ें।",
|
||||
endPlaceholder: "समाप्त",
|
||||
clear: "साफ़ करें",
|
||||
dropFileOrClick: "यहां 1 फ़ाइल छोड़ें या अपलोड करने के लिए क्लिक करें",
|
||||
viewDataset: "डेटासेट देखें",
|
||||
uploadFailed: "अपलोड विफल",
|
||||
unknownError: "अज्ञात त्रुटि",
|
||||
unsupportedFileType: "असमर्थित फ़ाइल प्रकार",
|
||||
uploadOneFileType: "एक {types} फ़ाइल अपलोड करें।",
|
||||
datasetUploaded: "डेटासेट अपलोड किया गया",
|
||||
evalDatasetUploaded: "Eval डेटासेट अपलोड किया गया",
|
||||
uploadOneFileAtATime: "एक बार में एक फ़ाइल अपलोड करें",
|
||||
uploadSingleFileDescription:
|
||||
"ट्रेनिंग डेटासेट अपलोड एक ही फ़ाइल स्वीकार करता है।",
|
||||
checkingToken: "token जांचा जा रहा है...",
|
||||
getOrUpdateToken: "token प्राप्त या अपडेट करें",
|
||||
preview: "डेटासेट का पूर्वावलोकन करें",
|
||||
split: "स्प्लिट",
|
||||
subset: "उपसमूह",
|
||||
s3: {
|
||||
title: "S3 कॉन्फ़िगरेशन",
|
||||
description:
|
||||
"Amazon S3 से .parquet, .json, .jsonl, या .csv डेटासेट लोड करें",
|
||||
bucket: "बकेट नाम",
|
||||
bucketPlaceholder: "my-training-data-bucket",
|
||||
region: "AWS क्षेत्र",
|
||||
regionPlaceholder: "us-east-1",
|
||||
prefix: "पथ प्रीफ़िक्स",
|
||||
prefixPlaceholder: "datasets/whisper/",
|
||||
prefixTooltip: "बकेट में आपकी डेटासेट फ़ाइलों का वैकल्पिक पथ",
|
||||
accessKeyId: "एक्सेस Key ID",
|
||||
accessKeyIdPlaceholder: "AKIAIOSFODNN7EXAMPLE",
|
||||
secretAccessKey: "सीक्रेट एक्सेस Key",
|
||||
secretAccessKeyPlaceholder: "आपकी AWS सीक्रेट एक्सेस key",
|
||||
useIamRole: "IAM Role का उपयोग करें",
|
||||
useIamRoleTooltip:
|
||||
"एक्सेस keys के बजाय IAM role क्रेडेंशियल का उपयोग करें (EC2/SageMaker के लिए अनुशंसित)",
|
||||
testConnection: "कनेक्शन जांचें",
|
||||
connectionSuccess: "S3 बकेट से सफलतापूर्वक कनेक्ट हुआ",
|
||||
connectionFailed: "S3 बकेट से कनेक्ट करने में विफल",
|
||||
comingSoon: "S3 एकीकरण जल्द आ रहा है",
|
||||
comingSoonDescription:
|
||||
"S3 डेटासेट लोडिंग के लिए boto3 आवश्यक है। यह सुविधा विकासाधीन है।",
|
||||
},
|
||||
},
|
||||
params: {
|
||||
title: "पैरामीटर",
|
||||
description: "ट्रेनिंग हाइपरपैरामीटर कॉन्फ़िगर करें",
|
||||
projectName: "प्रोजेक्ट नाम",
|
||||
optional: "वैकल्पिक",
|
||||
projectNameDescription:
|
||||
"ट्रेनिंग आउटपुट फ़ोल्डर नामों, एक्सपोर्ट डिफ़ॉल्ट, और इतिहास में उपयोग किया जाता है।",
|
||||
loraSettings: "LoRA सेटिंग्स",
|
||||
trainingHyperparameters: "ट्रेनिंग हाइपरपैरामीटर",
|
||||
maxSteps: "अधिकतम स्टेप्स",
|
||||
epochs: "एपॉक",
|
||||
useMaxSteps: "अधिकतम स्टेप्स का उपयोग करें",
|
||||
useEpochs: "एपॉक का उपयोग करें",
|
||||
maxStepsTooltip: "कुल ऑप्टिमाइज़र स्टेप्स को ओवरराइड करें।",
|
||||
epochsTooltip: "डेटासेट पर पूर्ण पास की संख्या।",
|
||||
epochsDescription: "प्रत्येक एपॉक आपके डेटासेट पर एक पूर्ण पास है।",
|
||||
maxStepsDescription:
|
||||
"ट्रेनिंग को ऑप्टिमाइज़र स्टेप्स की एक निश्चित संख्या तक सीमित करता है।",
|
||||
contextLength: "कॉन्टेक्स्ट लंबाई",
|
||||
contextLengthTooltip: "प्रति ट्रेनिंग सैंपल अधिकतम टोकन संख्या।",
|
||||
customContextLength: "एक कस्टम मान दर्ज करें",
|
||||
contextLengthDescription: "ट्रेनिंग सैंपल के लिए अधिकतम अनुक्रम लंबाई",
|
||||
learningRate: "लर्निंग रेट",
|
||||
learningRateTooltip:
|
||||
"वेट अपडेट के लिए स्टेप साइज़। कम मान धीमी लेकिन अधिक स्थिर ट्रेनिंग करते हैं।",
|
||||
learningRateDescription:
|
||||
"अनुशंसित: LoRA के लिए 2e-4, CPT के लिए 5e-5, फुल फ़ाइन-ट्यून के लिए 2e-5",
|
||||
embeddingLearningRate: "एम्बेडिंग लर्निंग रेट",
|
||||
embeddingLearningRateTooltip:
|
||||
"केवल तब उपयोग किया जाता है जब CPT embed_tokens को ट्रेन कर रहा हो। एम्बेडिंग LoRA वेट्स की तुलना में अधिक आसानी से अस्थिर हो जाती हैं, इसलिए उन्हें आमतौर पर एक छोटी LR की आवश्यकता होती है। lr/10 उपयोग करने के लिए खाली छोड़ें; सामान्य कार्यशील सीमा मुख्य LR से 2x-10x छोटी है। इसे केवल तभी बढ़ाएं जब शब्दावली या डोमेन-टोकन अनुकूलन बहुत धीमा हो।",
|
||||
embeddingLearningRateDescription:
|
||||
"lr/10 उपयोग करने के लिए खाली छोड़ें (अनुशंसित)। सामान्य सीमा मुख्य लर्निंग रेट से 2x-10x छोटी है।",
|
||||
rank: "Rank",
|
||||
rankTooltip:
|
||||
"लो-रैंक मैट्रिक्स का आयाम। अधिक = अधिक क्षमता।",
|
||||
alpha: "Alpha",
|
||||
alphaTooltip: "LoRA अपडेट के लिए स्केलिंग फ़ैक्टर। आमतौर पर rank का 2x।",
|
||||
dropout: "Dropout",
|
||||
dropoutTooltip:
|
||||
"ओवरफ़िटिंग कम करने के लिए LoRA लेयर्स के लिए dropout प्रायिकता।",
|
||||
visionLayers: "विज़न लेयर्स",
|
||||
languageLayers: "लैंग्वेज लेयर्स",
|
||||
attentionModules: "अटेंशन मॉड्यूल",
|
||||
mlpModules: "MLP मॉड्यूल",
|
||||
targetModules: "लक्ष्य मॉड्यूल",
|
||||
enableLora: "LoRA सक्षम करें",
|
||||
trainWithLora: "LoRA के साथ ट्रेन करें",
|
||||
stableRank: "स्थिर Rank",
|
||||
memoryEfficient: "मेमोरी कुशल",
|
||||
optimization: "ऑप्टिमाइज़ेशन",
|
||||
schedule: "शेड्यूल",
|
||||
memory: "मेमोरी",
|
||||
optimizer: "ऑप्टिमाइज़र",
|
||||
optimizerTooltip:
|
||||
"ऑप्टिमाइज़ेशन एल्गोरिदम। 8-बिट वेरिएंट मेमोरी उपयोग कम करते हैं। विज़न मॉडल के लिए Fused अनुशंसित है।",
|
||||
lrScheduler: "LR शेड्यूलर",
|
||||
lrSchedulerTooltip:
|
||||
"ट्रेनिंग के दौरान लर्निंग रेट कैसे बदलता है। Linear स्थिर रूप से घटता है; cosine एक वक्र में घटता है।",
|
||||
optimizerOptions: {
|
||||
adamw8bit: "AdamW 8-bit",
|
||||
pagedAdamw8bit: "Paged AdamW 8-bit",
|
||||
adamwBnb8bit: "AdamW BNB 8-bit",
|
||||
pagedAdamw32bit: "Paged AdamW 32-bit",
|
||||
adamwTorch: "AdamW (PyTorch)",
|
||||
adamwTorchFused: "AdamW (PyTorch Fused)",
|
||||
},
|
||||
lrSchedulerOptions: {
|
||||
linear: "Linear",
|
||||
cosine: "Cosine",
|
||||
},
|
||||
batchSize: "बैच साइज़",
|
||||
batchSizeTooltip: "प्रति स्टेप प्रोसेस किए गए सैंपल। अधिक होने पर अधिक VRAM उपयोग करता है।",
|
||||
gradAccum: "ग्रेडिएंट संचय",
|
||||
gradAccumTooltip: "अतिरिक्त VRAM के बिना बड़े बैच साइज़ का अनुकरण करता है।",
|
||||
weightDecay: "वेट डिके",
|
||||
weightDecayTooltip: "ओवरफ़िटिंग रोकने के लिए L2 रेगुलराइज़ेशन।",
|
||||
warmupSteps: "वार्मअप स्टेप्स",
|
||||
warmupStepsTooltip:
|
||||
"स्थिरता के लिए ट्रेनिंग की शुरुआत में LR को धीरे-धीरे बढ़ाएं।",
|
||||
scheduleEpochsTooltip:
|
||||
"डेटासेट पर पूर्ण पास की संख्या। अधिकतम स्टेप्स के अनुसार चलाने के लिए 0 सेट करें।",
|
||||
saveSteps: "सेव स्टेप्स",
|
||||
saveStepsTooltip: "हर N स्टेप्स पर एक चेकपॉइंट सहेजें। अक्षम करने के लिए 0।",
|
||||
evalSteps: "Eval स्टेप्स",
|
||||
evalStepsTooltip:
|
||||
"मूल्यांकनों के बीच कुल ट्रेनिंग स्टेप्स का अंश (0-1)। मूल्यांकन अक्षम करने के लिए 0 सेट करें। उदा. 0.01 = हर 1% स्टेप्स पर मूल्यांकन करें।",
|
||||
seed: "सीड",
|
||||
seedTooltip: "पुनरुत्पादन के लिए रैंडम seed।",
|
||||
gradCheckpoint: "ग्रेडिएंट चेकपॉइंट",
|
||||
gradCheckpointTooltip:
|
||||
"एक्टिवेशन को फिर से गणना करके कंप्यूट को मेमोरी से बदलें।",
|
||||
none: "कोई नहीं",
|
||||
standard: "मानक",
|
||||
enablePacking: "packing सक्षम करें",
|
||||
assistantCompletionsOnly: "केवल असिस्टेंट completions",
|
||||
readMore: "और पढ़ें",
|
||||
},
|
||||
training: {
|
||||
title: "ट्रेनिंग",
|
||||
description: "ट्रेनिंग की निगरानी और नियंत्रण करें",
|
||||
chartNoDataTitle: "अभी तक कोई ट्रेनिंग डेटा नहीं",
|
||||
chartNoDataDescription: "loss प्रगति देखने के लिए ट्रेनिंग शुरू करें",
|
||||
startTraining: "ट्रेनिंग शुरू करें",
|
||||
starting: "शुरू हो रहा है...",
|
||||
loadingModel: "मॉडल लोड हो रहा है...",
|
||||
checkingDataset: "डेटासेट जांचा जा रहा है...",
|
||||
configLabel: "ट्रेनिंग कॉन्फ़िग",
|
||||
upload: "अपलोड करें",
|
||||
uploadConfigTooltip: "एक सहेजा गया YAML कॉन्फ़िग लोड करें",
|
||||
save: "सहेजें",
|
||||
saveConfigTooltip: "वर्तमान कॉन्फ़िग को YAML के रूप में डाउनलोड करें",
|
||||
reset: "रीसेट करें",
|
||||
resetConfigTooltip: "मॉडल डिफ़ॉल्ट पर रीसेट करें",
|
||||
configLoaded: "कॉन्फ़िग लोड हुआ",
|
||||
failedToLoadConfig: "कॉन्फ़िग लोड करने में विफल",
|
||||
invalidYamlFile: "अमान्य YAML फ़ाइल",
|
||||
failedToReadFile: "फ़ाइल पढ़ने में विफल",
|
||||
parametersReset: "पैरामीटर मॉडल डिफ़ॉल्ट पर रीसेट किए गए",
|
||||
audioIncompatible:
|
||||
"यह मॉडल ऑडियो का समर्थन नहीं करता। एक ऑडियो-सक्षम मॉडल पर स्विच करें या एक गैर-ऑडियो डेटासेट चुनें।",
|
||||
visionIncompatible:
|
||||
"टेक्स्ट मॉडल मल्टीमॉडल डेटासेट के साथ संगत नहीं है। एक विज़न मॉडल पर स्विच करें या एक केवल-टेक्स्ट डेटासेट चुनें।",
|
||||
cancelTitle: "ट्रेनिंग रद्द करें",
|
||||
cancelDescription: "क्या आप वर्तमान ट्रेनिंग रन को रद्द करना चाहते हैं?",
|
||||
continueAction: "ट्रेनिंग जारी रखें",
|
||||
cancelAction: "ट्रेनिंग रद्द करें",
|
||||
stopTitle: "ट्रेनिंग रोकें",
|
||||
stopDescription: "चुनें कि आप वर्तमान ट्रेनिंग रन को कैसे रोकना चाहते हैं।",
|
||||
stopAction: "रोकें",
|
||||
stopping: "रोका जा रहा है...",
|
||||
stopAndSave: "रोकें और सहेजें",
|
||||
compareInChat: "चैट में तुलना करें",
|
||||
exportModel: "मॉडल एक्सपोर्ट करें",
|
||||
milestone: "मील का पत्थर",
|
||||
halfwayDone: "आधा हो गया। ट्रेनिंग 50% पार कर चुकी है।",
|
||||
doneNextStep:
|
||||
"ट्रेनिंग पूर्ण। अगला चरण: बेस बनाम फ़ाइन-ट्यून किए गए आउटपुट की तुलना करें।",
|
||||
},
|
||||
history: {
|
||||
title: "इतिहास",
|
||||
emptyTitle: "अभी तक कोई ट्रेनिंग रन नहीं",
|
||||
emptyDescription:
|
||||
"अभी तक कोई ट्रेनिंग रन नहीं। कॉन्फ़िगर टैब में अपनी पहली ट्रेनिंग रन शुरू करें।",
|
||||
loadError: "ट्रेनिंग रन लोड करने में विफल",
|
||||
deleteError: "ट्रेनिंग रन हटाने में विफल। कृपया पुनः प्रयास करें।",
|
||||
retry: "पुनः प्रयास करें",
|
||||
loadMore: "और लोड करें",
|
||||
loading: "लोड हो रहा है...",
|
||||
loadingRun: "ट्रेनिंग रन लोड हो रही है...",
|
||||
runNotFound: "रन नहीं मिली",
|
||||
deleteTitle: "ट्रेनिंग रन हटाएं?",
|
||||
deleteDescription:
|
||||
"यह इस ट्रेनिंग रन और इसके सभी मेट्रिक्स को स्थायी रूप से हटा देगा। इस कार्रवाई को पूर्ववत नहीं किया जा सकता।",
|
||||
runCount: "{count} रन",
|
||||
oneRun: "1 रन",
|
||||
resume: "फिर से शुरू करें",
|
||||
resumeTraining: "ट्रेनिंग फिर से शुरू करें",
|
||||
resuming: "फिर से शुरू हो रहा है...",
|
||||
deleteRun: "रन हटाएं",
|
||||
loss: "Loss",
|
||||
steps: "स्टेप्स",
|
||||
lossTrendSparkline: "Loss ट्रेंड स्पार्कलाइन",
|
||||
relativeJustNow: "अभी",
|
||||
relativeMinutesAgo: "{count} मिनट पहले",
|
||||
relativeHoursAgo: "{count} घंटे पहले",
|
||||
relativeDaysAgo: "{count} दिन पहले",
|
||||
status: {
|
||||
completed: "पूर्ण",
|
||||
stopped: "रोका गया",
|
||||
error: "त्रुटि",
|
||||
running: "चल रहा है",
|
||||
continued: "जारी रखा गया",
|
||||
},
|
||||
message: {
|
||||
completed: "ट्रेनिंग पूर्ण हुई",
|
||||
stopped: "ट्रेनिंग रोकी गई",
|
||||
running: "ट्रेनिंग जारी है",
|
||||
errored: "ट्रेनिंग में त्रुटि हुई",
|
||||
},
|
||||
copyPreviewLink: "पूर्वावलोकन लिंक कॉपी करें",
|
||||
previewLinkCopied: "पूर्वावलोकन लिंक कॉपी किया गया",
|
||||
previewLinkCopyFailed: "लिंक कॉपी नहीं किया जा सका",
|
||||
},
|
||||
charts: {
|
||||
settings: "चार्ट सेटिंग्स",
|
||||
settingsDescription:
|
||||
"ट्रेनिंग चलते रहने के दौरान चार्ट प्रस्तुति को समायोजित करें।",
|
||||
openSettings: "चार्ट सेटिंग्स खोलें",
|
||||
viewWindow: "व्यू विंडो",
|
||||
viewWindowDescription: "केवल नवीनतम स्टेप्स या पूरा इतिहास दिखाएं।",
|
||||
window: "विंडो",
|
||||
all: "सभी",
|
||||
trainingLoss: "ट्रेनिंग Loss",
|
||||
trainingLossDescription: "ओवरले और EMA स्मूदिंग को नियंत्रित करें।",
|
||||
smoothing: "स्मूदिंग",
|
||||
smoothingDescription: "अधिक स्मूदिंग के लिए दाईं ओर ले जाएं। `0` = कच्चा।",
|
||||
showRawLoss: "कच्चा loss दिखाएं",
|
||||
showSmoothedLoss: "स्मूद किया गया loss दिखाएं",
|
||||
showAverageLine: "औसत रेखा दिखाएं",
|
||||
scaleAndCleanup: "स्केल और क्लीनअप",
|
||||
linear: "Linear",
|
||||
log: "Log",
|
||||
noClip: "कोई clip नहीं",
|
||||
clipP99: "क्लिप p99",
|
||||
clipP95: "क्लिप p95",
|
||||
lossAxis: "Loss अक्ष",
|
||||
gradientNormAxis: "ग्रेडिएंट नॉर्म अक्ष",
|
||||
learningRateAxis: "लर्निंग रेट अक्ष",
|
||||
resetDefaults: "डिफ़ॉल्ट रीसेट करें",
|
||||
loss: "Loss",
|
||||
smoothed: "स्मूद किया गया",
|
||||
evalLoss: "मूल्यांकन Loss",
|
||||
learningRate: "लर्निंग रेट",
|
||||
lr: "LR",
|
||||
gradNorm: "ग्रेडिएंट नॉर्म",
|
||||
gradientNorm: "ग्रेडिएंट नॉर्म",
|
||||
step: "स्टेप {step}",
|
||||
averageValue: "औसत {value}",
|
||||
waitingForFirstEvaluationStep: "पहले मूल्यांकन स्टेप की प्रतीक्षा में...",
|
||||
evaluationNotConfigured: "मूल्यांकन कॉन्फ़िगर नहीं किया गया",
|
||||
evalChartWillAppear: "eval_steps तक पहुंचने पर चार्ट दिखाई देगा",
|
||||
setEvalDatasetAndSteps:
|
||||
"eval loss ट्रैक करने के लिए eval डेटासेट और eval_steps सेट करें",
|
||||
},
|
||||
progress: {
|
||||
title: "ट्रेनिंग प्रगति",
|
||||
liveMetrics: "लाइव ट्रेनिंग मेट्रिक्स",
|
||||
exportGguf: "GGUF में एक्सपोर्ट करें",
|
||||
openConfig: "ट्रेनिंग कॉन्फ़िग खोलें",
|
||||
configLabel: "ट्रेनिंग कॉन्फ़िग",
|
||||
hyperparams: "हाइपरपैराम्स",
|
||||
epochs: "एपॉक",
|
||||
batchSize: "बैच साइज़",
|
||||
learningRate: "लर्निंग रेट",
|
||||
optimizer: "ऑप्टिमाइज़र",
|
||||
maxSteps: "अधिकतम स्टेप्स",
|
||||
contextLength: "कॉन्टेक्स्ट लंबाई",
|
||||
warmupSteps: "वार्मअप स्टेप्स",
|
||||
rank: "Rank",
|
||||
alpha: "Alpha",
|
||||
dropout: "Dropout",
|
||||
variant: "वेरिएंट",
|
||||
epoch: "एपॉक {value}",
|
||||
percentComplete: "{percent}% पूर्ण",
|
||||
stepProgress: "स्टेप {current} / {total}",
|
||||
loss: "Loss",
|
||||
lr: "LR",
|
||||
gradNorm: "ग्रेडिएंट नॉर्म",
|
||||
project: "प्रोजेक्ट",
|
||||
model: "मॉडल",
|
||||
method: "विधि",
|
||||
elapsed: "बीता समय: {value}",
|
||||
eta: "ETA: {value}",
|
||||
stepsPerSecond: "{value} स्टेप्स/से",
|
||||
noStepsPerSecond: "-- स्टेप्स/से",
|
||||
tokens: "टोकन: {value}",
|
||||
gpuMonitor: "GPU मॉनिटर",
|
||||
live: "लाइव",
|
||||
utilization: "उपयोग",
|
||||
temperature: "तापमान",
|
||||
vram: "VRAM",
|
||||
power: "पावर",
|
||||
phase: {
|
||||
idle: "निष्क्रिय",
|
||||
downloadingModel: "मॉडल डाउनलोड हो रहा है",
|
||||
downloadingDataset: "डेटासेट डाउनलोड हो रहा है",
|
||||
loadingModel: "मॉडल लोड हो रहा है",
|
||||
loadingDataset: "डेटासेट लोड हो रहा है",
|
||||
configuring: "कॉन्फ़िगर हो रहा है",
|
||||
training: "ट्रेनिंग हो रही है",
|
||||
completed: "पूर्ण",
|
||||
error: "त्रुटि",
|
||||
stopped: "रोका गया",
|
||||
},
|
||||
},
|
||||
trainingStart: {
|
||||
ready: "तैयार",
|
||||
downloading: "डाउनलोड हो रहा है",
|
||||
preparing: "तैयार हो रहा है",
|
||||
left: "{eta} शेष",
|
||||
downloaded: "{size} डाउनलोड किया गया",
|
||||
terminalStart: "> unsloth ट्रेनिंग शुरू हो रही है...",
|
||||
preparingResources: "> मॉडल और डेटासेट तैयार हो रहे हैं...",
|
||||
gettingReady: "> हम आपकी रन के लिए सब कुछ तैयार कर रहे हैं...",
|
||||
waitingForFirstStep: "> {message} | पहले स्टेप की प्रतीक्षा में... ({step})",
|
||||
resumingTraining: "ट्रेनिंग फिर से शुरू हो रही है...",
|
||||
startingTraining: "ट्रेनिंग शुरू हो रही है...",
|
||||
dataset: "डेटासेट",
|
||||
datasetStreaming: "डेटासेट: स्ट्रीमिंग (कोई पूर्ण डाउनलोड नहीं)",
|
||||
modelWeights: "मॉडल वेट्स",
|
||||
},
|
||||
tour: {
|
||||
guidedTour: "गाइडेड टूर",
|
||||
},
|
||||
},
|
||||
} satisfies DeepPartialMessageTree<typeof en>;
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved.
|
||||
// See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import type { DeepPartialMessageTree } from "../types";
|
||||
import type { en } from "./en";
|
||||
|
||||
export const ja = {
|
||||
common: {
|
||||
cancel: "キャンセル",
|
||||
|
|
@ -38,10 +41,11 @@ export const ja = {
|
|||
compare: "比較",
|
||||
search: "検索",
|
||||
hub: "ハブ",
|
||||
train: "トレイン",
|
||||
train: "トレーニング",
|
||||
recipes: "レシピ",
|
||||
export: "エクスポート",
|
||||
recents: "履歴",
|
||||
noChatsYet: "チャットがまだありません",
|
||||
settings: "設定",
|
||||
api: "API",
|
||||
lightMode: "ライトモード",
|
||||
|
|
@ -93,6 +97,7 @@ export const ja = {
|
|||
general: "一般",
|
||||
profile: "プロフィール",
|
||||
appearance: "外観",
|
||||
resources: "システム",
|
||||
chat: "チャット",
|
||||
connections: "接続",
|
||||
apiKeys: "API",
|
||||
|
|
@ -136,6 +141,18 @@ export const ja = {
|
|||
loadError: "Helper LLM 設定の読み込みに失敗しました。",
|
||||
saveError: "Helper LLM 設定の保存に失敗しました。",
|
||||
},
|
||||
modelAutoSwitch: {
|
||||
sectionTitle: "モデル自動切り替え (OpenAI API)",
|
||||
enable: "リクエストごとにモデルを切り替え",
|
||||
enableDescription: "OpenAI互換のリクエストが別のダウンロード済み GGUF を指定した場合、応答する前にそのモデルを読み込みます。デフォルトはオフです。不明な名前の場合は、読み込み済みのモデルで応答を続けます。",
|
||||
idleUnload: "アイドル時の自動アンロード",
|
||||
idleUnloadDescription: "指定した秒数だけアイドル状態が続くとモデルをアンロードして VRAM を解放します。次のリクエストで再読み込みされます。0 にすると読み込んだままにします。",
|
||||
idleNeedsEnable: "アンロードされたモデルが次回使用時に再読み込みされるように、「リクエストごとにモデルを切り替え」をオンにしてください。",
|
||||
idleActiveViaEnv: "アイドル時の自動アンロードは UNSLOTH_MODEL_IDLE_TTL 環境変数によって有効になっています。",
|
||||
loadError: "モデル自動切り替え設定の読み込みに失敗しました。",
|
||||
saveError: "モデル自動切り替え設定の保存に失敗しました。",
|
||||
idleError: "秒数を整数(0 以上)で入力してください。",
|
||||
},
|
||||
previewSharing: {
|
||||
sectionTitle: "プレビュー共有",
|
||||
enableLabel: "公開プレビューリンク",
|
||||
|
|
@ -166,6 +183,18 @@ export const ja = {
|
|||
maxUploadSize: "トレーニングデータセットのアップロード容量制限",
|
||||
maxUploadSizeDescription: "デフォルトは {defaultSize} MB です。",
|
||||
},
|
||||
rag: {
|
||||
sectionTitle: "ドキュメントと RAG",
|
||||
embeddingModel: "埋め込みモデル",
|
||||
embeddingModelDescription: "ドキュメントのインデックス作成と検索に使用する Hugging Face モデルまたはローカルパス。デフォルトは {defaultModel} です。",
|
||||
reindexWarning: "新しくインデックスされるドキュメントにのみ影響します。モデルを変更した後は、既存のドキュメントを再アップロードしてください。",
|
||||
emptyError: "Hugging Face モデル ID またはローカルパスを入力してください。",
|
||||
loadError: "埋め込みモデル設定の読み込みに失敗しました。",
|
||||
saveError: "埋め込みモデルの保存に失敗しました。",
|
||||
saved: "埋め込みモデルを保存しました。",
|
||||
saveAnyway: "そのまま保存",
|
||||
resetAction: "デフォルトに戻す",
|
||||
},
|
||||
storage: {
|
||||
sectionTitle: "ストレージ",
|
||||
modelsFolder: "モデルフォルダ",
|
||||
|
|
@ -222,6 +251,7 @@ export const ja = {
|
|||
title: "言語",
|
||||
label: "表示言語",
|
||||
description: "Unsloth で使用される言語。",
|
||||
autoDetect: "自動検出",
|
||||
},
|
||||
layout: {
|
||||
title: "レイアウト",
|
||||
|
|
@ -229,6 +259,58 @@ export const ja = {
|
|||
compactSidebarDescription: "サイドバーをアイコンに折りたたまず、展開したままにします。",
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
title: "システム",
|
||||
description: "この Studio サーバーのハードウェアとストレージを監視します。",
|
||||
liveUpdates: "リアルタイム更新",
|
||||
floatingWindow: "フローティングウィンドウ",
|
||||
disableOverlay: "オーバーレイを無効化",
|
||||
liveMonitor: {
|
||||
title: "リアルタイムモニター",
|
||||
cpu: "CPU",
|
||||
ram: "RAM",
|
||||
disk: "ディスク",
|
||||
vram: "VRAM",
|
||||
cpuCores: "論理 {logical} / 物理 {physical} コア",
|
||||
currentLoad: "現在の負荷",
|
||||
free: "{value} 空き",
|
||||
noGpu: "認識できる GPU がありません",
|
||||
},
|
||||
gpu: {
|
||||
title: "GPU デバイス",
|
||||
noGpu: "認識できる GPU が検出されませんでした。上には CPU のみのリソースが表示されています。",
|
||||
unknownDevice: "不明な GPU",
|
||||
deviceWithIndex: "GPU {index}",
|
||||
vramUtilization: "VRAM",
|
||||
used: "{value} 使用中",
|
||||
free: "{value} 空き",
|
||||
total: "{value} 合計",
|
||||
},
|
||||
storage: {
|
||||
title: "ストレージ",
|
||||
systemDisk: "システムディスク",
|
||||
diskUsage: "{used} 使用中 / {total}",
|
||||
diskFree: "{free} 空き",
|
||||
modelsFolder: "モデルフォルダ",
|
||||
modelsFolderDescription: "ダウンロードしたモデルの保存先。",
|
||||
openAction: "開く",
|
||||
copyAction: "パスをコピー",
|
||||
copied: "パスをコピーしました",
|
||||
openError: "フォルダを開けませんでした",
|
||||
copyError: "パスをコピーできませんでした",
|
||||
},
|
||||
environment: {
|
||||
title: "環境",
|
||||
backend: "バックエンド",
|
||||
python: "Python",
|
||||
torch: "Torch",
|
||||
transformers: "Transformers",
|
||||
uptime: "稼働時間",
|
||||
processMemory: "プロセスメモリ",
|
||||
notInstalled: "未インストール",
|
||||
unknown: "不明",
|
||||
},
|
||||
},
|
||||
chat: {
|
||||
title: "チャット",
|
||||
description: "このデバイスに保存されているチャット履歴を管理します。",
|
||||
|
|
@ -313,8 +395,10 @@ export const ja = {
|
|||
usageTools: "ツール",
|
||||
exampleCurlTools: "curl + ツール",
|
||||
examplePythonTools: "Python + ツール",
|
||||
exampleJavaScriptTools: "JavaScript + ツール",
|
||||
exampleCurlAdvanced: "curl + 高度な設定",
|
||||
examplePythonAdvanced: "Python + 高度な設定",
|
||||
exampleJavaScriptAdvanced: "JavaScript + 高度な設定",
|
||||
osUnix: "Linux / macOS / WSL",
|
||||
osWindows: "Windows",
|
||||
secureHttps: "セキュア HTTPS",
|
||||
|
|
@ -324,6 +408,11 @@ export const ja = {
|
|||
copy: "コピー",
|
||||
copied: "コピーしました",
|
||||
setupDocs: "セットアップドキュメント:",
|
||||
codingAgents: "コーディングエージェント",
|
||||
codingAgentsHint: "このサーバーに対してコーディングエージェントを起動します。読み込み済みのモデルを使用します。ローカルサーバーでは API キーが自動的に発行され、リモートサーバーではコマンドに含まれます。",
|
||||
codingAgentsSwap: "claude を codex、openclaw、opencode、hermes、pi に置き換えられます。",
|
||||
codingAgentDetected: "このマシンにインストール済み",
|
||||
codingAgentsDetectedHint: "このマシンで検出されました: {agents}。",
|
||||
relativeNever: "なし",
|
||||
relativeJustNow: "たった今",
|
||||
relativeHoursAgo: "{count}時間前",
|
||||
|
|
@ -405,7 +494,7 @@ export const ja = {
|
|||
},
|
||||
},
|
||||
studio: {
|
||||
routeTitle: "トレイン",
|
||||
routeTitle: "トレーニング",
|
||||
title: "Fine-tuning Studio",
|
||||
subtitles: {
|
||||
configure: "設定とトレーニングの開始",
|
||||
|
|
@ -448,7 +537,7 @@ export const ja = {
|
|||
scanning: "スキャン中...",
|
||||
scanningLocalModels: "ローカルモデルをスキャン中...",
|
||||
noLocalModelsFound: "ローカルモデルが見つかりません",
|
||||
noLocalModelsFoundManual: "ローカルモデルが見つかりません。パスを手動を入力してください。",
|
||||
noLocalModelsFoundManual: "ローカルモデルが見つかりません。パスを手動で入力してください。",
|
||||
failedToLoadLocalModels: "ローカルモデルの読み込みに失敗しました",
|
||||
hfCache: "HF キャッシュ",
|
||||
customFolders: "カスタムフォルダ",
|
||||
|
|
@ -583,7 +672,7 @@ export const ja = {
|
|||
rank: "Rank",
|
||||
rankTooltip: "低ランク行列の次元数。高いほど表現能力が向上します。",
|
||||
alpha: "Alpha",
|
||||
alphaTooltip: "LoRA 更新のスクール係数。通常は rank の 2 倍に設定します。",
|
||||
alphaTooltip: "LoRA 更新のスケール係数。通常は rank の 2 倍に設定します。",
|
||||
dropout: "Dropout",
|
||||
dropoutTooltip: "過学習を抑えるための LoRA レイヤーのドロップアウト確率。",
|
||||
visionLayers: "ビジョンレイヤー",
|
||||
|
|
@ -626,7 +715,7 @@ export const ja = {
|
|||
saveSteps: "保存ステップ間隔",
|
||||
saveStepsTooltip: "N ステップごとにチェックポイントを保存します。0 で無効化します。",
|
||||
evalSteps: "評価ステップ間隔",
|
||||
evalStepsTooltip: "評価を行う総トレーニングステップ of 割合 (0-1)。0 に設定すると評価が無効になります。例: 0.01 = ステップの 1% ごとに評価を実行。",
|
||||
evalStepsTooltip: "評価を行う間隔を、総トレーニングステップに対する割合 (0-1) で指定します。0 に設定すると評価が無効になります。例: 0.01 = ステップの 1% ごとに評価を実行。",
|
||||
seed: "シード値",
|
||||
seedTooltip: "再現性のための乱数シード。",
|
||||
gradCheckpoint: "勾配チェックポイント",
|
||||
|
|
@ -828,4 +917,4 @@ export const ja = {
|
|||
guidedTour: "ガイドツアー",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
} satisfies DeepPartialMessageTree<typeof en>;
|
||||
|
|
|
|||
1002
studio/frontend/src/i18n/locales/ko.ts
Normal file
1002
studio/frontend/src/i18n/locales/ko.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,9 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import type { DeepPartialMessageTree } from "../types";
|
||||
import type { en } from "./en";
|
||||
|
||||
export const ptBR = {
|
||||
common: {
|
||||
cancel: "Cancelar",
|
||||
|
|
@ -41,6 +44,7 @@ export const ptBR = {
|
|||
recipes: "Receitas",
|
||||
export: "Exportar",
|
||||
recents: "Recentes",
|
||||
noChatsYet: "Nenhum chat ainda",
|
||||
settings: "Configurações",
|
||||
api: "API",
|
||||
lightMode: "Modo Claro",
|
||||
|
|
@ -143,6 +147,41 @@ export const ptBR = {
|
|||
loadError: "Falha ao carregar as configurações do LLM Auxiliar.",
|
||||
saveError: "Falha ao salvar as configurações do LLM Auxiliar.",
|
||||
},
|
||||
modelAutoSwitch: {
|
||||
sectionTitle: "Troca automática de modelo (API OpenAI)",
|
||||
enable: "Trocar de modelo por requisição",
|
||||
enableDescription:
|
||||
"Quando uma requisição compatível com OpenAI nomear um GGUF baixado diferente, carrega-o antes de responder. Desativado por padrão; nomes desconhecidos continuam usando o modelo carregado.",
|
||||
idleUnload: "Descarregamento automático por inatividade",
|
||||
idleUnloadDescription:
|
||||
"Descarrega o modelo após esta quantidade de segundos de inatividade para liberar VRAM; a próxima requisição o recarrega. 0 mantém o modelo carregado.",
|
||||
idleNeedsEnable:
|
||||
"Ative Trocar de modelo por requisição para que um modelo descarregado seja recarregado no próximo uso.",
|
||||
idleActiveViaEnv:
|
||||
"O descarregamento automático por inatividade está ativo por meio da variável de ambiente UNSLOTH_MODEL_IDLE_TTL.",
|
||||
loadError: "Falha ao carregar as configurações de troca automática de modelo.",
|
||||
saveError: "Falha ao salvar as configurações de troca automática de modelo.",
|
||||
idleError: "Insira um número inteiro de segundos (0 ou mais).",
|
||||
},
|
||||
previewSharing: {
|
||||
sectionTitle: "Compartilhamento de pré-visualização",
|
||||
enableLabel: "Links públicos de pré-visualização",
|
||||
enableDescription:
|
||||
"Permite que qualquer pessoa com um link assinado converse com um modelo concluído, sem necessidade de login. Desative para tirar a superfície de pré-visualização pública do ar; os links compartilhados param de funcionar.",
|
||||
loadError: "Falha ao carregar as configurações de compartilhamento de pré-visualização.",
|
||||
saveError: "Falha ao salvar as configurações de compartilhamento de pré-visualização.",
|
||||
revokeLabel: "Revogar todos os links de pré-visualização",
|
||||
revokeDescription:
|
||||
"Rotaciona o segredo de assinatura para que todos os links que você compartilhou parem de funcionar. Links copiados recentemente continuam funcionando.",
|
||||
revokeAction: "Revogar links",
|
||||
revoking: "Revogando...",
|
||||
revokeConfirmTitle: "Revogar todos os links de pré-visualização?",
|
||||
revokeConfirmDescription:
|
||||
"Todos os links de pré-visualização que você compartilhou pararão de funcionar imediatamente. Isso não pode ser desfeito.",
|
||||
revokeConfirmAction: "Revogar todos os links",
|
||||
revoked: "Todos os links de pré-visualização foram revogados",
|
||||
revokeError: "Não foi possível revogar os links de pré-visualização",
|
||||
},
|
||||
notifications: {
|
||||
sectionTitle: "Notificações",
|
||||
showLlamaUpdates: "Notificações de atualização do llama.cpp",
|
||||
|
|
@ -160,6 +199,20 @@ export const ptBR = {
|
|||
maxUploadSizeDescription:
|
||||
"O padrão é {defaultSize} MB.",
|
||||
},
|
||||
rag: {
|
||||
sectionTitle: "Documentos e RAG",
|
||||
embeddingModel: "Modelo de embedding",
|
||||
embeddingModelDescription:
|
||||
"Modelo do Hugging Face ou caminho local usado para indexar e buscar seus documentos. O padrão é {defaultModel}.",
|
||||
reindexWarning:
|
||||
"Afeta apenas documentos recém-indexados. Reenvie os documentos existentes após alterar o modelo.",
|
||||
emptyError: "Insira um id de modelo do Hugging Face ou um caminho local.",
|
||||
loadError: "Falha ao carregar a configuração do modelo de embedding.",
|
||||
saveError: "Falha ao salvar o modelo de embedding.",
|
||||
saved: "Modelo de embedding salvo.",
|
||||
saveAnyway: "Salvar mesmo assim",
|
||||
resetAction: "Redefinir para o padrão",
|
||||
},
|
||||
storage: {
|
||||
sectionTitle: "Armazenamento",
|
||||
modelsFolder: "Pasta de modelos",
|
||||
|
|
@ -221,6 +274,7 @@ export const ptBR = {
|
|||
title: "Idioma",
|
||||
label: "Idioma de exibição",
|
||||
description: "O idioma utilizado pelo Unsloth.",
|
||||
autoDetect: "Detecção automática",
|
||||
},
|
||||
layout: {
|
||||
title: "Layout",
|
||||
|
|
@ -368,7 +422,7 @@ export const ptBR = {
|
|||
createError: "Não foi possível criar o token de acesso.",
|
||||
revokeError: "Não foi possível revogar o token de acesso.",
|
||||
never: "Nunca",
|
||||
tokenNamePlaceholder: "Nome do token (ex: producao)",
|
||||
tokenNamePlaceholder: "Nome do token (ex: produção)",
|
||||
newAccessTokenName: "Nome do novo token de acesso",
|
||||
createToken: "Criar token",
|
||||
creating: "Criando...",
|
||||
|
|
@ -394,6 +448,12 @@ export const ptBR = {
|
|||
copy: "Copiar",
|
||||
copied: "Copiado",
|
||||
setupDocs: "Docs de configuração:",
|
||||
codingAgents: "Agentes de código",
|
||||
codingAgentsHint:
|
||||
"Inicie um agente de código conectado a este servidor. Ele usa o modelo carregado; um servidor local gera uma chave de API automaticamente, um remoto a inclui no comando.",
|
||||
codingAgentsSwap: "Troque claude por codex, openclaw, opencode, hermes ou pi.",
|
||||
codingAgentDetected: "Instalado nesta máquina",
|
||||
codingAgentsDetectedHint: "Detectado nesta máquina: {agents}.",
|
||||
relativeNever: "nunca",
|
||||
relativeJustNow: "agora mesmo",
|
||||
relativeHoursAgo: "há {count}h",
|
||||
|
|
@ -646,6 +706,10 @@ export const ptBR = {
|
|||
params: {
|
||||
title: "Parâmetros",
|
||||
description: "Configure os hiperparâmetros de treinamento",
|
||||
projectName: "Nome do Projeto",
|
||||
optional: "Opcional",
|
||||
projectNameDescription:
|
||||
"Usado nos nomes das pastas de saída do treinamento, nos padrões de exportação e no histórico.",
|
||||
loraSettings: "Configurações do LoRA",
|
||||
trainingHyperparameters: "Hiperparâmetros de Treinamento",
|
||||
maxSteps: "Passos Máximos (Max Steps)",
|
||||
|
|
@ -762,11 +826,11 @@ export const ptBR = {
|
|||
visionIncompatible:
|
||||
"O modelo de texto não é compatível com um dataset multimodal. Mude para um modelo de visão ou escolha um dataset apenas de texto.",
|
||||
cancelTitle: "Cancelar Treinamento",
|
||||
cancelDescription: "Deseja cancelar a execução de treinamento atual?",
|
||||
cancelDescription: "Deseja cancelar a execução de treino atual?",
|
||||
continueAction: "Continuar Treinamento",
|
||||
cancelAction: "Cancelar Treinamento",
|
||||
stopTitle: "Interromper Treinamento",
|
||||
stopDescription: "Escolha como você deseja interromper a execução de treinamento atual.",
|
||||
stopDescription: "Escolha como você deseja interromper a execução de treino atual.",
|
||||
stopAction: "Interromper",
|
||||
stopping: "Interrompendo...",
|
||||
stopAndSave: "Interromper e Salvar",
|
||||
|
|
@ -818,6 +882,9 @@ export const ptBR = {
|
|||
running: "Treinamento em andamento",
|
||||
errored: "Treinamento com erro",
|
||||
},
|
||||
copyPreviewLink: "Copiar link de pré-visualização",
|
||||
previewLinkCopied: "Link de pré-visualização copiado",
|
||||
previewLinkCopyFailed: "Não foi possível copiar o link",
|
||||
},
|
||||
charts: {
|
||||
settings: "Configurações do Gráfico",
|
||||
|
|
@ -884,6 +951,7 @@ export const ptBR = {
|
|||
loss: "Loss",
|
||||
lr: "LR",
|
||||
gradNorm: "Norma do Grad.",
|
||||
project: "Projeto",
|
||||
model: "Modelo",
|
||||
method: "Método",
|
||||
elapsed: "Decorrido: {value}",
|
||||
|
|
@ -930,4 +998,4 @@ export const ptBR = {
|
|||
guidedTour: "Tour Guiado",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
} satisfies DeepPartialMessageTree<typeof en>;
|
||||
|
|
|
|||
999
studio/frontend/src/i18n/locales/ru.ts
Normal file
999
studio/frontend/src/i18n/locales/ru.ts
Normal file
|
|
@ -0,0 +1,999 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
||||
|
||||
import type { DeepPartialMessageTree } from "../types";
|
||||
import type { en } from "./en";
|
||||
|
||||
export const ru = {
|
||||
common: {
|
||||
cancel: "Отмена",
|
||||
close: "Закрыть",
|
||||
delete: "Удалить",
|
||||
done: "Готово",
|
||||
error: "Ошибка",
|
||||
export: "Экспорт",
|
||||
help: "Справка",
|
||||
loading: "Загрузка...",
|
||||
new: "Создать",
|
||||
rename: "Переименовать",
|
||||
save: "Сохранить",
|
||||
saving: "Сохранение...",
|
||||
search: "Поиск",
|
||||
shutdown: "Выключить",
|
||||
},
|
||||
shell: {
|
||||
beta: "BETA",
|
||||
brand: "unsloth",
|
||||
product: "Unsloth Studio",
|
||||
accountMenu: "Меню аккаунта {name}",
|
||||
updateAvailable: "Доступно обновление",
|
||||
aria: {
|
||||
home: "Главная Unsloth",
|
||||
closeSidebar: "Закрыть боковую панель",
|
||||
openSidebar: "Открыть боковую панель",
|
||||
chatOptions: "Параметры чата",
|
||||
runOptions: "Параметры запуска",
|
||||
},
|
||||
navigation: {
|
||||
newChat: "Новый чат",
|
||||
returnToChat: "Вернуться к чату",
|
||||
compare: "Сравнить",
|
||||
search: "Поиск",
|
||||
hub: "Hub",
|
||||
train: "Обучение",
|
||||
recipes: "Рецепты",
|
||||
export: "Экспорт",
|
||||
recents: "Недавние",
|
||||
noChatsYet: "Пока нет чатов",
|
||||
settings: "Настройки",
|
||||
api: "API",
|
||||
lightMode: "Светлая тема",
|
||||
darkMode: "Тёмная тема",
|
||||
guidedTour: "Обзорный тур",
|
||||
help: "Справка",
|
||||
logOut: "Выйти",
|
||||
shutdown: "Выключить",
|
||||
},
|
||||
notFound: {
|
||||
title: "Страница не найдена",
|
||||
description: "{path} не существует.",
|
||||
backToChat: "Вернуться к чату",
|
||||
},
|
||||
dialog: {
|
||||
deleteChat: {
|
||||
title: "Удалить чат",
|
||||
description: 'Вы уверены, что хотите удалить чат «{name}»?',
|
||||
},
|
||||
deleteRun: {
|
||||
title: "Удалить запуск обучения",
|
||||
description: 'Вы уверены, что хотите удалить запуск «{name}»?',
|
||||
},
|
||||
renameChat: {
|
||||
title: "Переименовать чат",
|
||||
placeholder: "Название чата",
|
||||
},
|
||||
renameRun: {
|
||||
title: "Переименовать запуск",
|
||||
placeholder: "Название запуска",
|
||||
},
|
||||
},
|
||||
toast: {
|
||||
cannotDeleteRunningRun: "Нельзя удалить выполняющийся запуск обучения",
|
||||
failedToDeleteChat: "Не удалось удалить чат",
|
||||
failedToDeleteRun: "Не удалось удалить запуск",
|
||||
failedToRenameChat: "Не удалось переименовать чат",
|
||||
failedToRenameRun: "Не удалось переименовать запуск",
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
title: "Настройки",
|
||||
dialog: {
|
||||
title: "Настройки",
|
||||
description: "Управление настройками Unsloth.",
|
||||
closeAriaLabel: "Закрыть настройки",
|
||||
},
|
||||
tabs: {
|
||||
general: "Общие",
|
||||
profile: "Профиль",
|
||||
appearance: "Оформление",
|
||||
resources: "Система",
|
||||
chat: "Чат",
|
||||
connections: "Подключения",
|
||||
apiKeys: "API",
|
||||
about: "О программе",
|
||||
},
|
||||
general: {
|
||||
title: "Общие",
|
||||
description: "Глобальные настройки Unsloth.",
|
||||
account: "Аккаунт",
|
||||
huggingFaceToken: "Токен Hugging Face",
|
||||
huggingFaceTokenDescription:
|
||||
"Используется для загрузки закрытых моделей и публикации артефактов.",
|
||||
hideToken: "Скрыть токен",
|
||||
showToken: "Показать токен",
|
||||
tokenSaved: "Токен сохранён",
|
||||
password: "Пароль",
|
||||
passwordDescription: "Изменить пароль для этого аккаунта Studio.",
|
||||
passwordDialog: {
|
||||
trigger: "Изменить пароль",
|
||||
title: "Изменить пароль",
|
||||
description:
|
||||
"Введите текущий пароль и выберите новый (не менее {minLength} символов).",
|
||||
currentPassword: "Текущий пароль",
|
||||
newPassword: "Новый пароль",
|
||||
confirmPassword: "Подтвердите новый пароль",
|
||||
currentTooShort:
|
||||
"Текущий пароль должен содержать не менее {minLength} символов.",
|
||||
newTooShort: "Новый пароль должен содержать не менее {minLength} символов.",
|
||||
mismatch: "Пароли не совпадают.",
|
||||
samePassword:
|
||||
"Новый пароль должен отличаться от текущего.",
|
||||
update: "Обновить пароль",
|
||||
updating: "Обновление...",
|
||||
updated: "Пароль обновлён.",
|
||||
updateFailed: "Не удалось обновить пароль.",
|
||||
},
|
||||
chatDefaults: "Настройки чата по умолчанию",
|
||||
autoTitleNewChats: "Автоматически называть новые чаты",
|
||||
autoTitleNewChatsDescription:
|
||||
"Создавать короткое название по первому сообщению.",
|
||||
helperLlm: {
|
||||
sectionTitle: "Вспомогательная LLM",
|
||||
preloadOnStartup: "Предзагружать вспомогательную LLM при запуске",
|
||||
preloadOnStartupDescription:
|
||||
"Загружать вспомогательную модель AI Assist в фоне при запуске. По умолчанию выключено; AI Assist всё равно может загрузить её по запросу.",
|
||||
disabledByEnv:
|
||||
"Отключено переменной UNSLOTH_HELPER_MODEL_DISABLE в окружении бэкенда.",
|
||||
loadError: "Не удалось загрузить настройки вспомогательной LLM.",
|
||||
saveError: "Не удалось сохранить настройки вспомогательной LLM.",
|
||||
},
|
||||
modelAutoSwitch: {
|
||||
sectionTitle: "Автопереключение модели (OpenAI API)",
|
||||
enable: "Переключать модель по запросу",
|
||||
enableDescription:
|
||||
"Когда OpenAI-совместимый запрос указывает другую загруженную GGUF, загружать её перед обслуживанием. По умолчанию выключено; неизвестные имена продолжают обслуживать загруженную модель.",
|
||||
idleUnload: "Автовыгрузка при простое",
|
||||
idleUnloadDescription:
|
||||
"Выгружать модель после указанного числа секунд простоя, чтобы освободить VRAM; следующий запрос загрузит её снова. 0 оставляет модель загруженной.",
|
||||
idleNeedsEnable:
|
||||
"Включите «Переключать модель по запросу», чтобы выгруженная модель загружалась при следующем использовании.",
|
||||
idleActiveViaEnv:
|
||||
"Автовыгрузка при простое активна через переменную окружения UNSLOTH_MODEL_IDLE_TTL.",
|
||||
loadError: "Не удалось загрузить настройки автопереключения модели.",
|
||||
saveError: "Не удалось сохранить настройки автопереключения модели.",
|
||||
idleError: "Введите целое число секунд (0 или больше).",
|
||||
},
|
||||
previewSharing: {
|
||||
sectionTitle: "Публикация предпросмотра",
|
||||
enableLabel: "Публичные ссылки предпросмотра",
|
||||
enableDescription:
|
||||
"Позволяет любому по подписанной ссылке общаться с готовой моделью без входа в систему. Отключите, чтобы закрыть публичный предпросмотр; общие ссылки перестанут работать.",
|
||||
loadError: "Не удалось загрузить настройки публикации предпросмотра.",
|
||||
saveError: "Не удалось сохранить настройки публикации предпросмотра.",
|
||||
revokeLabel: "Отозвать все ссылки предпросмотра",
|
||||
revokeDescription:
|
||||
"Сменить секрет подписи, чтобы все опубликованные ссылки перестали работать. Ссылки, скопированные заново, продолжат работать.",
|
||||
revokeAction: "Отозвать ссылки",
|
||||
revoking: "Отзыв...",
|
||||
revokeConfirmTitle: "Отозвать все ссылки предпросмотра?",
|
||||
revokeConfirmDescription:
|
||||
"Все опубликованные ссылки предпросмотра немедленно перестанут работать. Это действие нельзя отменить.",
|
||||
revokeConfirmAction: "Отозвать все ссылки",
|
||||
revoked: "Все ссылки предпросмотра отозваны",
|
||||
revokeError: "Не удалось отозвать ссылки предпросмотра",
|
||||
},
|
||||
notifications: {
|
||||
sectionTitle: "Уведомления",
|
||||
showLlamaUpdates: "Уведомления об обновлениях llama.cpp",
|
||||
showLlamaUpdatesDescription:
|
||||
"Уведомлять о доступности новой сборки llama.cpp для запуска новых моделей. Отключите, если вы только обучаете модели.",
|
||||
},
|
||||
gettingStarted: "Начало работы",
|
||||
startOnboarding: "Запустить онбординг",
|
||||
startOnboardingDescription:
|
||||
"Снова открыть мастер настройки, не изменяя ваш аккаунт.",
|
||||
startOnboardingAction: "Запустить онбординг",
|
||||
uploads: {
|
||||
sectionTitle: "Загрузки",
|
||||
maxUploadSize: "Лимит загрузки датасета для обучения",
|
||||
maxUploadSizeDescription: "По умолчанию {defaultSize} МБ.",
|
||||
},
|
||||
rag: {
|
||||
sectionTitle: "Документы и RAG",
|
||||
embeddingModel: "Модель эмбеддингов",
|
||||
embeddingModelDescription:
|
||||
"Модель Hugging Face или локальный путь для индексации и поиска по вашим документам. По умолчанию {defaultModel}.",
|
||||
reindexWarning:
|
||||
"Влияет только на вновь индексируемые документы. После смены модели загрузите существующие документы заново.",
|
||||
emptyError: "Введите ID модели Hugging Face или локальный путь.",
|
||||
loadError: "Не удалось загрузить настройку модели эмбеддингов.",
|
||||
saveError: "Не удалось сохранить модель эмбеддингов.",
|
||||
saved: "Модель эмбеддингов сохранена.",
|
||||
saveAnyway: "Всё равно сохранить",
|
||||
resetAction: "Сбросить к умолчанию",
|
||||
},
|
||||
storage: {
|
||||
sectionTitle: "Хранилище",
|
||||
modelsFolder: "Папка моделей",
|
||||
modelsFolderDescription: "Где хранятся загруженные модели.",
|
||||
openAction: "Открыть",
|
||||
copyAction: "Копировать путь",
|
||||
copied: "Путь скопирован",
|
||||
openError: "Не удалось открыть папку",
|
||||
copyError: "Не удалось скопировать путь",
|
||||
},
|
||||
resetPreferences: {
|
||||
sectionTitle: "Опасная зона",
|
||||
label: "Сбросить все локальные настройки",
|
||||
description:
|
||||
"Очищает только локальные настройки. Чаты, доступ по API и настройки в базе данных сохраняются.",
|
||||
action: "Сбросить настройки",
|
||||
confirmTitle: "Сбросить все локальные настройки?",
|
||||
confirmDescription:
|
||||
"Очищает только локальные настройки и перезагружает Unsloth. Чаты, доступ по API и настройки в базе данных сохраняются.",
|
||||
confirmAction: "Сбросить и перезагрузить",
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
title: "Профиль",
|
||||
description: "Как ваш профиль отображается в Unsloth.",
|
||||
changePicture: "Изменить фото профиля",
|
||||
displayName: "Отображаемое имя",
|
||||
nickname: "Как Unsloth к вам обращаться?",
|
||||
nicknamePlaceholder: "Псевдоним",
|
||||
nicknameSaved: "Предпочитаемое имя сохранено",
|
||||
avatarShape: "Форма фото профиля",
|
||||
avatarShapeCircle: "Круг",
|
||||
avatarShapeRounded: "Скруглённый",
|
||||
chooseSloth: "Или выберите ленивца",
|
||||
nameSaved: "Имя профиля сохранено",
|
||||
namePersistErrorTitle: "Не удалось сохранить имя профиля",
|
||||
namePersistErrorDescription:
|
||||
"Имя обновлено для этой сессии, но может не сохраниться после перезагрузки.",
|
||||
photoUpdated: "Фото профиля обновлено",
|
||||
photoPersistErrorTitle: "Не удалось сохранить фото профиля",
|
||||
photoPersistErrorDescription:
|
||||
"Фото обновлено для этой сессии, но может не сохраниться после перезагрузки.",
|
||||
photoUpdateErrorTitle: "Не удалось обновить фото профиля",
|
||||
imageUseError: "Не удалось использовать это изображение.",
|
||||
},
|
||||
appearance: {
|
||||
title: "Оформление",
|
||||
description: "Как Unsloth Studio выглядит на этом устройстве.",
|
||||
theme: {
|
||||
title: "Тема",
|
||||
label: "Цветовая схема",
|
||||
description: "Светлая, тёмная или как в системе.",
|
||||
system: "Системная",
|
||||
light: "Светлая",
|
||||
dark: "Тёмная",
|
||||
},
|
||||
language: {
|
||||
title: "Язык",
|
||||
label: "Язык интерфейса",
|
||||
description: "Язык, используемый Unsloth.",
|
||||
autoDetect: "Автоопределение",
|
||||
},
|
||||
layout: {
|
||||
title: "Макет",
|
||||
compactSidebar: "Закреплять боковую панель по умолчанию",
|
||||
compactSidebarDescription:
|
||||
"Держать боковую панель развёрнутой, а не свёрнутой в значки.",
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
title: "Система",
|
||||
description: "Мониторинг оборудования и хранилища этого сервера Studio.",
|
||||
liveUpdates: "Обновления в реальном времени",
|
||||
floatingWindow: "Плавающее окно",
|
||||
disableOverlay: "Отключить оверлей",
|
||||
liveMonitor: {
|
||||
title: "Монитор в реальном времени",
|
||||
cpu: "CPU",
|
||||
ram: "RAM",
|
||||
disk: "Диск",
|
||||
vram: "VRAM",
|
||||
cpuCores: "{logical} логич. / {physical} физич. ядер",
|
||||
currentLoad: "Текущая нагрузка",
|
||||
free: "{value} свободно",
|
||||
noGpu: "GPU не обнаружен",
|
||||
},
|
||||
gpu: {
|
||||
title: "Устройства GPU",
|
||||
noGpu: "Видимый GPU не обнаружен. Выше показаны ресурсы CPU.",
|
||||
unknownDevice: "Неизвестный GPU",
|
||||
deviceWithIndex: "GPU {index}",
|
||||
vramUtilization: "VRAM",
|
||||
used: "{value} использовано",
|
||||
free: "{value} свободно",
|
||||
total: "{value} всего",
|
||||
},
|
||||
storage: {
|
||||
title: "Хранилище",
|
||||
systemDisk: "Системный диск",
|
||||
diskUsage: "{used} использовано / {total}",
|
||||
diskFree: "{free} свободно",
|
||||
modelsFolder: "Папка моделей",
|
||||
modelsFolderDescription: "Где хранятся загруженные модели.",
|
||||
openAction: "Открыть",
|
||||
copyAction: "Копировать путь",
|
||||
copied: "Путь скопирован",
|
||||
openError: "Не удалось открыть папку",
|
||||
copyError: "Не удалось скопировать путь",
|
||||
},
|
||||
environment: {
|
||||
title: "Окружение",
|
||||
backend: "Бэкенд",
|
||||
python: "Python",
|
||||
torch: "Torch",
|
||||
transformers: "Transformers",
|
||||
uptime: "Время работы",
|
||||
processMemory: "Память процесса",
|
||||
notInstalled: "Не установлено",
|
||||
unknown: "Неизвестно",
|
||||
},
|
||||
},
|
||||
chat: {
|
||||
title: "Чат",
|
||||
description: "Управление историей чатов, хранящейся на этом устройстве.",
|
||||
modelDisclaimer: "Показывать оговорку о модели",
|
||||
modelDisclaimerDescription:
|
||||
'Показывать «LLM могут ошибаться» под полем ввода.',
|
||||
artifacts: {
|
||||
title: "Canvas",
|
||||
collapseHtmlBlocks: "Сворачивать блоки HTML",
|
||||
collapseHtmlBlocksDescription:
|
||||
"Режим Canvas автоматически сворачивает полный HTML. Включите, чтобы также сворачивать HTML-документы в блоках кода, когда Canvas выключен.",
|
||||
allowNetworkAccess: "Разрешить сетевой доступ Canvas",
|
||||
allowNetworkAccessDescription:
|
||||
"Позволяет предпросмотрам Canvas загружать скрипты, стили, шрифты, медиа и сетевые ресурсы из CDN. Оставьте выключенным для полностью офлайн-предпросмотров.",
|
||||
},
|
||||
data: "Данные",
|
||||
exportHistory: "Экспортировать историю чатов",
|
||||
exportHistoryDescription: "Скачать все чаты и сообщения в формате JSON.",
|
||||
exportAction: "Экспорт",
|
||||
exportingAction: "Экспорт...",
|
||||
exportConversations: "Экспортировать «Недавние» и проекты",
|
||||
exportConversationsDescription:
|
||||
"Скачать «Недавние» или «Недавние» вместе с чатами проектов в формате Raw JSONL, CSV или ShareGPT JSONL, объединённо или по чатам.",
|
||||
exportConversationsAction: "Экспорт",
|
||||
exportScopeRecents: "Недавние",
|
||||
exportScopeAll: "Недавние + проекты",
|
||||
exportCombinedSuffix: "(объединённо)",
|
||||
exportPerChatSuffix: "(по чатам)",
|
||||
importChats: "Импортировать чаты",
|
||||
importChatsDescription:
|
||||
"Импортировать экспорт JSONL, NDJSON или CSV в «Недавние».",
|
||||
importChatsAction: "Импорт",
|
||||
importNoConversations: "В файле не найдено диалогов.",
|
||||
importedOneChat: "Импортирован 1 диалог в «Недавние».",
|
||||
importedChatCount: "Импортировано диалогов в «Недавние»: {count}.",
|
||||
importFailed: "Импорт не удался.",
|
||||
clearHistory: "Очистить историю чатов",
|
||||
clearHistoryDescription: "Удалить историю чатов с этого устройства.",
|
||||
clearAction: "Очистить",
|
||||
clearAllChats: "Очистить все чаты",
|
||||
clearAllChatsDescription: "Безвозвратно удалить все чаты на этом устройстве.",
|
||||
noChatsToClear: "Нет чатов для очистки.",
|
||||
clearOneChatDescription:
|
||||
"Безвозвратно удалить единственный чат на этом устройстве.",
|
||||
clearChatCountDescription:
|
||||
"Безвозвратно удалить все чаты на этом устройстве: {count}.",
|
||||
clearChatsAction: "Очистить чаты",
|
||||
clearOneChatTitle: "Очистить 1 чат?",
|
||||
clearChatsTitle: "Очистить {count} чатов?",
|
||||
clearChatsConfirmDescription:
|
||||
"Безвозвратно удаляет все чаты на этом устройстве. Это действие нельзя отменить.",
|
||||
clearingAction: "Очистка...",
|
||||
clearOneChatAction: "Очистить 1 чат",
|
||||
clearChatCountAction: "Очистить {count} чатов",
|
||||
clearedAllChats: "Все чаты очищены",
|
||||
clearedOneChat: "Очищен 1 чат",
|
||||
clearedChatCount: "Очищено чатов: {count}",
|
||||
someChatsCouldNotBeCleared: "Некоторые чаты не удалось очистить",
|
||||
chatsClearedRemainOne:
|
||||
"Очищено чатов: {clearedCount}; остался 1 чат. Повторите попытку.",
|
||||
chatsClearedRemain:
|
||||
"Очищено чатов: {clearedCount}; осталось чатов: {remainingCount}. Повторите попытку.",
|
||||
oneChatClearedRemain:
|
||||
"Очищен 1 чат; осталось чатов: {remainingCount}. Повторите попытку.",
|
||||
oneChatClearedRemainOne: "Очищен 1 чат; остался 1 чат. Повторите попытку.",
|
||||
storageClearFailedOne:
|
||||
"Не удалось очистить хранилище; возможно, остался 1 чат. Повторите попытку.",
|
||||
storageClearFailed:
|
||||
"Не удалось очистить хранилище; возможно, осталось чатов: {count}. Повторите попытку.",
|
||||
failedToClearChats: "Не удалось очистить чаты",
|
||||
},
|
||||
connections: {
|
||||
title: "Подключения",
|
||||
description: "Управление провайдерами и внешними подключениями.",
|
||||
},
|
||||
apiKeys: {
|
||||
title: "API",
|
||||
description: "Доступ к Unsloth через OpenAI-совместимый API.",
|
||||
readDocs: "Читать документацию API",
|
||||
noAccess: "Доступа к API пока нет.",
|
||||
accessTokens: "Токены доступа",
|
||||
loadError: "Не удалось загрузить доступ к API.",
|
||||
createError: "Не удалось создать токен доступа.",
|
||||
revokeError: "Не удалось отозвать токен доступа.",
|
||||
never: "Никогда",
|
||||
tokenNamePlaceholder: "Имя токена (например, production)",
|
||||
newAccessTokenName: "Имя нового токена доступа",
|
||||
createToken: "Создать токен",
|
||||
creating: "Создание...",
|
||||
newTokenCreated: "Новый токен доступа создан",
|
||||
accessTokenCopied: "Токен доступа скопирован",
|
||||
copyAccessToken: "Копировать токен доступа",
|
||||
copyNow: "Скопируйте сейчас: он больше не будет показан.",
|
||||
usageExamples: "Примеры использования",
|
||||
usageTools: "Инструменты",
|
||||
exampleCurlTools: "curl + инструменты",
|
||||
examplePythonTools: "Python + инструменты",
|
||||
exampleJavaScriptTools: "JavaScript + инструменты",
|
||||
exampleCurlAdvanced: "curl + расширенное",
|
||||
examplePythonAdvanced: "Python + расширенное",
|
||||
exampleJavaScriptAdvanced: "JavaScript + расширенное",
|
||||
osUnix: "Linux / macOS / WSL",
|
||||
osWindows: "Windows",
|
||||
secureHttps: "Защищённый HTTPS",
|
||||
secureHttpsHint:
|
||||
"Порт 0.0.0.0 по-прежнему доступен глобально. Для полной безопасности запустите Unsloth Studio с флагом --secure, чтобы открыть только эту HTTPS-ссылку.",
|
||||
copyTunnelUrl: "Копировать URL туннеля",
|
||||
copySnippet: "Копировать фрагмент",
|
||||
copy: "Копировать",
|
||||
copied: "Скопировано",
|
||||
setupDocs: "Документация по настройке:",
|
||||
codingAgents: "Кодинг-агенты",
|
||||
codingAgentsHint:
|
||||
"Запустите кодинг-агента к этому серверу. Он использует загруженную модель; локальный сервер выпускает ключ API автоматически, удалённый включает его в команду.",
|
||||
codingAgentsSwap: "Замените claude на codex, openclaw, opencode, hermes или pi.",
|
||||
codingAgentDetected: "Установлен на этой машине",
|
||||
codingAgentsDetectedHint: "Обнаружены на этой машине: {agents}.",
|
||||
relativeNever: "никогда",
|
||||
relativeJustNow: "только что",
|
||||
relativeHoursAgo: "{count} ч назад",
|
||||
relativeDaysAgo: "{count} дн назад",
|
||||
relativeMonthsAgo: "{count} мес назад",
|
||||
relativeYearsAgo: "{count} г назад",
|
||||
expired: "истёк",
|
||||
today: "сегодня",
|
||||
inDays: "через {count} дн",
|
||||
created: "Создан {value}",
|
||||
used: "Использован {value}",
|
||||
expires: "Истекает {value}",
|
||||
actionsFor: "Действия для {name}",
|
||||
copyPrefix: "Копировать префикс",
|
||||
revokeToken: "Отозвать токен",
|
||||
revokeTitle: 'Отозвать токен доступа «{name}»?',
|
||||
revokeDescription:
|
||||
"Приложения, использующие этот токен, немедленно потеряют доступ. Это действие нельзя отменить.",
|
||||
revokeAction: 'Отозвать «{name}»',
|
||||
revoking: "Отзыв...",
|
||||
},
|
||||
about: {
|
||||
title: "О программе",
|
||||
description: "Документация, заметки о выпусках, отзывы и данные сборки.",
|
||||
studioVersion: "Версия Unsloth",
|
||||
packageVersion: "Версия пакета",
|
||||
llamaCppVersion: "Версия llama.cpp",
|
||||
hardware: "Оборудование",
|
||||
gpu: "GPU",
|
||||
cuda: "CUDA",
|
||||
rocm: "ROCm",
|
||||
updates: "Обновление",
|
||||
help: "Справка",
|
||||
documentation: "Документация",
|
||||
releaseNotes: "Заметки о выпуске",
|
||||
whatsNew: "Что нового",
|
||||
feedback: "Отзывы",
|
||||
reportIssue: "Сообщить о проблеме",
|
||||
license: {
|
||||
sectionTitle: "Лицензия",
|
||||
studioLabel: "Unsloth Studio",
|
||||
studioLicense: "AGPL-3.0",
|
||||
studioDescription: "Открытый исходный код под GNU AGPL v3.0.",
|
||||
libraryLabel: "Unsloth Core",
|
||||
libraryLicense: "Apache-2.0",
|
||||
libraryDescription: "Лицензировано под Apache 2.0.",
|
||||
},
|
||||
dangerZone: "Опасная зона",
|
||||
shutDownStudio: "Выключить Unsloth Studio",
|
||||
shutDownStudioDescription:
|
||||
"Останавливает сервер Unsloth и завершает вашу сессию.",
|
||||
shutDown: "Выключить",
|
||||
update: {
|
||||
title: "Обновить Unsloth Studio",
|
||||
commandText: "Текст «{label}»",
|
||||
copied: "Скопировано",
|
||||
copyCommand: "Копировать команду",
|
||||
commandCopied: "«{label}» скопировано",
|
||||
copyNamedCommand: "Копировать «{label}»",
|
||||
checkingInstall: "Проверка способа установки Unsloth...",
|
||||
installIntro: "Чтобы установить или обновить Unsloth:",
|
||||
localUpdateHeading: "Локальное обновление",
|
||||
installCommandUnix: "Команда установки для macOS/Linux",
|
||||
installCommandWindows: "Команда установки для Windows",
|
||||
localInstallDetected:
|
||||
"Обнаружена локальная установка. Обновляйте из исходного checkout, чтобы не заменить его версией с PyPI.",
|
||||
pullThenUpdate:
|
||||
"Загрузите последние изменения, затем запустите локальный установщик:",
|
||||
gitPullCommand: "Команда git pull",
|
||||
localInstallerCommand: "Команда локального установщика",
|
||||
sourceInstallDetected:
|
||||
"Обнаружена установка из исходников или VCS-пакета. Переустановите из исходного локального пути или Git URL.",
|
||||
repoCheckoutFallback:
|
||||
"Если у вас всё ещё есть checkout репозитория, запустите локальный установщик из него:",
|
||||
restartAfterUpdate: "После обновления перезапустите Unsloth.",
|
||||
desktopManaged:
|
||||
"Настольное приложение поддерживает встроенный бэкенд в актуальном состоянии и уведомит о новой версии.",
|
||||
unknownInstall:
|
||||
"Не удалось определить способ установки Unsloth. Для установки через установщик или PyPI используйте команды выше.",
|
||||
localCheckout:
|
||||
"Для установок из локального checkout запустите локальный установщик из него:",
|
||||
docs: "Документация по установке:",
|
||||
docsInstall: "Установка",
|
||||
docsUpdating: "Обновление",
|
||||
docsMac: "Mac",
|
||||
docsWindows: "Windows",
|
||||
},
|
||||
},
|
||||
},
|
||||
studio: {
|
||||
routeTitle: "Обучение",
|
||||
title: "Студия дообучения",
|
||||
subtitles: {
|
||||
configure: "Настройте и запустите обучение",
|
||||
trainingInProgress: "Обучение выполняется",
|
||||
viewPastRuns: "Просмотр прошлых запусков обучения",
|
||||
viewingPastRun: "Просмотр прошлого запуска",
|
||||
},
|
||||
tabs: {
|
||||
configure: "Настройка",
|
||||
currentRun: "Текущий запуск",
|
||||
history: "История",
|
||||
},
|
||||
loadingRuntime: "Загрузка среды обучения...",
|
||||
backToHistory: "Назад к истории",
|
||||
sections: {
|
||||
model: "Модель",
|
||||
dataset: "Датасет",
|
||||
params: "Параметры",
|
||||
training: "Обучение",
|
||||
charts: "Графики",
|
||||
progress: "Прогресс обучения",
|
||||
},
|
||||
configure: {
|
||||
title: "Настройка",
|
||||
description: "Выберите модель, датасет и параметры обучения.",
|
||||
startTraining: "Начать обучение",
|
||||
starting: "Запуск...",
|
||||
loadingModel: "Загрузка модели...",
|
||||
checkingDataset: "Проверка датасета...",
|
||||
trainingConfig: "Конфигурация обучения",
|
||||
},
|
||||
model: {
|
||||
title: "Модель",
|
||||
description: "Выберите базовую модель и метод обучения",
|
||||
fasterTrainingBadge: "Обучение в 2 раза быстрее",
|
||||
baseModel: "Базовая модель",
|
||||
localModel: "Локальная модель",
|
||||
localModelTooltip:
|
||||
"Путь к локально загруженной модели или пользовательскому репозиторию HF.",
|
||||
scanningLocalAndCachedModels: "Сканирование локальных и кэшированных моделей...",
|
||||
scanning: "Сканирование...",
|
||||
scanningLocalModels: "Сканирование локальных моделей...",
|
||||
noLocalModelsFound: "Локальные модели не найдены",
|
||||
noLocalModelsFoundManual: "Локальные модели не найдены. Введите путь вручную.",
|
||||
failedToLoadLocalModels: "Не удалось загрузить локальные модели",
|
||||
hfCache: "Кэш HF",
|
||||
customFolders: "Пользовательские папки",
|
||||
localDir: "Локальный каталог",
|
||||
huggingFaceModel: "Модель Hugging Face",
|
||||
huggingFaceModelTooltip:
|
||||
"Ищите модели Hugging Face или выберите из нашего рекомендованного списка.",
|
||||
searchModels: "Поиск моделей...",
|
||||
searching: "Поиск...",
|
||||
noModelsFound: "Модели не найдены",
|
||||
needsVram: "Требуется ~{vram} ГБ VRAM (GPU: {gpu} ГБ)",
|
||||
tightVram: "~{vram} ГБ VRAM (впритык на {gpu} ГБ)",
|
||||
vramEstimate: "~{vram} ГБ VRAM",
|
||||
method: "Метод",
|
||||
methodTooltip:
|
||||
"QLoRA использует 4-битную квантизацию для минимального VRAM. LoRA использует 16 бит. Full обновляет все веса. CPT (Continued Pretraining) обучает на сыром тексте, чтобы адаптировать модель к новой предметной области без чат-форматирования.",
|
||||
readMore: "Подробнее",
|
||||
fullFineTune: "Полное дообучение",
|
||||
checkingToken: "Проверка токена...",
|
||||
getOrUpdateToken: "Получить или обновить токен",
|
||||
huggingFaceTokenOptional: "Токен Hugging Face (необязательно)",
|
||||
continuedPretraining: "Продолженное предобучение",
|
||||
localModels: "Локальные модели",
|
||||
localModelsFound: "Найдено локальных/кэшированных моделей: {count}",
|
||||
loadingLocalModels: "Загрузка локальных моделей...",
|
||||
},
|
||||
dataset: {
|
||||
title: "Датасет",
|
||||
description: "Выберите или загрузите данные для обучения",
|
||||
source: "Источник датасета",
|
||||
chooseDataset: "Выбрать датасет",
|
||||
chooseDatasetTooltip:
|
||||
"Используйте вкладки во всплывающем окне для переключения между Hugging Face и выводом локальных рецептов.",
|
||||
localTab: "Локальные",
|
||||
searchHuggingFaceDatasets: "Поиск датасетов Hugging Face...",
|
||||
searchLocalDatasets: "Поиск локальных датасетов...",
|
||||
searching: "Поиск...",
|
||||
noDatasetsFound: "Датасеты не найдены",
|
||||
loadingLocalDatasets: "Загрузка локальных датасетов...",
|
||||
failedToLoadLocalDatasets: "Не удалось загрузить локальные датасеты.",
|
||||
noLocalDatasetsYet: "Пока нет локальных датасетов.",
|
||||
noLocalDatasetsMatchSearch: "Нет локальных датасетов по запросу.",
|
||||
openDataRecipes: "Открыть Data Recipes",
|
||||
browsingSource: "Просмотр {browsing}. Текущий выбор остаётся {current}.",
|
||||
localDatasets: "Локальные датасеты",
|
||||
localDataset: "Локальный датасет",
|
||||
localDatasetRows: " / {count} строк",
|
||||
huggingFaceDataset: "Датасет Hugging Face",
|
||||
localDatasetMetadata: "Метаданные локального датасета",
|
||||
dataRecipeOutput: "Вывод Data Recipe.",
|
||||
rows: "Строки",
|
||||
columns: "Столбцы",
|
||||
batches: "Батчи",
|
||||
updated: "Обновлено",
|
||||
evalDataset: "Датасет для оценки",
|
||||
uploading: "Загрузка...",
|
||||
upload: "Загрузить",
|
||||
uploadEvalFile: "Загрузить файл для оценки",
|
||||
evalDatasetDescription:
|
||||
"Необязательно. Если не указан, небольшая часть будет выделена из обучающих данных.",
|
||||
advanced: "Дополнительно",
|
||||
targetFormat: "Целевой формат",
|
||||
targetFormatTooltip:
|
||||
"Формат ваших обучающих данных. Автоопределение работает для большинства датасетов.",
|
||||
auto: "Авто",
|
||||
rawText: "Сырой текст",
|
||||
trainSplitStart: "Начало обучающей выборки",
|
||||
trainSplitStartTooltip:
|
||||
"Обучаться только на подмножестве обучающей выборки, указав индекс начальной строки (включительно, с нуля). Оставьте пустым, чтобы начать с первой строки.",
|
||||
trainSplitEnd: "Конец обучающей выборки",
|
||||
trainSplitEndTooltip:
|
||||
"Индекс последней строки из обучающей выборки (включительно, с нуля). Например, задайте Начало 0 и Конец 99, чтобы обучаться на первых 100 строках. Оставьте пустым, чтобы использовать все оставшиеся строки.",
|
||||
endPlaceholder: "Конец",
|
||||
clear: "Очистить",
|
||||
dropFileOrClick: "Перетащите 1 файл сюда или нажмите для загрузки",
|
||||
viewDataset: "Просмотреть датасет",
|
||||
uploadFailed: "Загрузка не удалась",
|
||||
unknownError: "Неизвестная ошибка",
|
||||
unsupportedFileType: "Неподдерживаемый тип файла",
|
||||
uploadOneFileType: "Загрузите один файл {types}.",
|
||||
datasetUploaded: "Датасет загружен",
|
||||
evalDatasetUploaded: "Датасет для оценки загружен",
|
||||
uploadOneFileAtATime: "Загружайте по одному файлу за раз",
|
||||
uploadSingleFileDescription:
|
||||
"Загрузка датасета для обучения принимает один файл.",
|
||||
checkingToken: "Проверка токена...",
|
||||
getOrUpdateToken: "Получить или обновить токен",
|
||||
preview: "Предпросмотр датасета",
|
||||
split: "Выборка",
|
||||
subset: "Подмножество",
|
||||
s3: {
|
||||
title: "Конфигурация S3",
|
||||
description:
|
||||
"Загрузка датасетов .parquet, .json, .jsonl или .csv из Amazon S3",
|
||||
bucket: "Имя бакета",
|
||||
bucketPlaceholder: "my-training-data-bucket",
|
||||
region: "Регион AWS",
|
||||
regionPlaceholder: "us-east-1",
|
||||
prefix: "Префикс пути",
|
||||
prefixPlaceholder: "datasets/whisper/",
|
||||
prefixTooltip: "Необязательный путь в бакете к файлам вашего датасета",
|
||||
accessKeyId: "Access Key ID",
|
||||
accessKeyIdPlaceholder: "AKIAIOSFODNN7EXAMPLE",
|
||||
secretAccessKey: "Secret Access Key",
|
||||
secretAccessKeyPlaceholder: "Ваш AWS secret access key",
|
||||
useIamRole: "Использовать роль IAM",
|
||||
useIamRoleTooltip:
|
||||
"Использовать учётные данные роли IAM вместо ключей доступа (рекомендуется для EC2/SageMaker)",
|
||||
testConnection: "Проверить подключение",
|
||||
connectionSuccess: "Успешное подключение к бакету S3",
|
||||
connectionFailed: "Не удалось подключиться к бакету S3",
|
||||
comingSoon: "Интеграция с S3 скоро появится",
|
||||
comingSoonDescription:
|
||||
"Загрузка датасетов из S3 требует boto3. Эта функция в разработке.",
|
||||
},
|
||||
},
|
||||
params: {
|
||||
title: "Параметры",
|
||||
description: "Настройте гиперпараметры обучения",
|
||||
projectName: "Название проекта",
|
||||
optional: "Необязательно",
|
||||
projectNameDescription:
|
||||
"Используется в именах папок вывода обучения, значениях экспорта по умолчанию и истории.",
|
||||
loraSettings: "Настройки LoRA",
|
||||
trainingHyperparameters: "Гиперпараметры обучения",
|
||||
maxSteps: "Макс. шагов",
|
||||
epochs: "Эпохи",
|
||||
useMaxSteps: "Использовать макс. шаги",
|
||||
useEpochs: "Использовать эпохи",
|
||||
maxStepsTooltip: "Переопределить общее число шагов оптимизатора.",
|
||||
epochsTooltip: "Количество полных проходов по датасету.",
|
||||
epochsDescription: "Каждая эпоха представляет собой один полный проход по вашему датасету.",
|
||||
maxStepsDescription:
|
||||
"Ограничивает обучение фиксированным числом шагов оптимизатора.",
|
||||
contextLength: "Длина контекста",
|
||||
contextLengthTooltip: "Максимальное число токенов на обучающий образец.",
|
||||
customContextLength: "Введите своё значение",
|
||||
contextLengthDescription: "Макс. длина последовательности для обучающих образцов",
|
||||
learningRate: "Скорость обучения",
|
||||
learningRateTooltip:
|
||||
"Размер шага обновления весов. Меньшие значения обучают медленнее, но стабильнее.",
|
||||
learningRateDescription:
|
||||
"Рекомендуется: 2e-4 для LoRA, 5e-5 для CPT, 2e-5 для полного дообучения",
|
||||
embeddingLearningRate: "Скорость обучения эмбеддингов",
|
||||
embeddingLearningRateTooltip:
|
||||
"Используется только когда CPT обучает embed_tokens. Эмбеддинги легче дестабилизировать, чем веса LoRA, поэтому им обычно нужна меньшая скорость обучения. Оставьте пустым, чтобы использовать lr/10; типичный рабочий диапазон в 2-10 раз меньше основной скорости обучения. Повышайте только если адаптация словаря или доменных токенов идёт слишком медленно.",
|
||||
embeddingLearningRateDescription:
|
||||
"Оставьте пустым, чтобы использовать lr/10 (рекомендуется). Типичный диапазон в 2-10 раз меньше основной скорости обучения.",
|
||||
rank: "Ранг",
|
||||
rankTooltip:
|
||||
"Размерность низкоранговых матриц. Чем выше, тем больше ёмкость.",
|
||||
alpha: "Alpha",
|
||||
alphaTooltip: "Коэффициент масштабирования обновлений LoRA. Обычно 2× ранга.",
|
||||
dropout: "Dropout",
|
||||
dropoutTooltip:
|
||||
"Вероятность dropout для слоёв LoRA для уменьшения переобучения.",
|
||||
visionLayers: "Слои зрения",
|
||||
languageLayers: "Языковые слои",
|
||||
attentionModules: "Модули внимания",
|
||||
mlpModules: "Модули MLP",
|
||||
targetModules: "Целевые модули",
|
||||
enableLora: "Включить LoRA",
|
||||
trainWithLora: "Обучать с LoRA",
|
||||
stableRank: "Стабильный ранг",
|
||||
memoryEfficient: "Экономия памяти",
|
||||
optimization: "Оптимизация",
|
||||
schedule: "Расписание",
|
||||
memory: "Память",
|
||||
optimizer: "Оптимизатор",
|
||||
optimizerTooltip:
|
||||
"Алгоритм оптимизации. 8-битные варианты снижают потребление памяти. Fused рекомендуется для моделей зрения.",
|
||||
lrScheduler: "Планировщик LR",
|
||||
lrSchedulerTooltip:
|
||||
"Как скорость обучения меняется в процессе обучения. Linear убывает равномерно; cosine убывает по кривой.",
|
||||
optimizerOptions: {
|
||||
adamw8bit: "AdamW 8-bit",
|
||||
pagedAdamw8bit: "Paged AdamW 8-bit",
|
||||
adamwBnb8bit: "AdamW BNB 8-bit",
|
||||
pagedAdamw32bit: "Paged AdamW 32-bit",
|
||||
adamwTorch: "AdamW (PyTorch)",
|
||||
adamwTorchFused: "AdamW (PyTorch Fused)",
|
||||
},
|
||||
lrSchedulerOptions: {
|
||||
linear: "Линейный",
|
||||
cosine: "Косинусный",
|
||||
},
|
||||
batchSize: "Размер батча",
|
||||
batchSizeTooltip: "Образцов на шаг. Чем больше, тем больше VRAM.",
|
||||
gradAccum: "Накопление градиента",
|
||||
gradAccumTooltip: "Имитирует больший размер батча без дополнительного VRAM.",
|
||||
weightDecay: "Затухание весов",
|
||||
weightDecayTooltip: "L2-регуляризация для предотвращения переобучения.",
|
||||
warmupSteps: "Шаги прогрева",
|
||||
warmupStepsTooltip:
|
||||
"Постепенно повышать LR в начале обучения для стабильности.",
|
||||
scheduleEpochsTooltip:
|
||||
"Количество полных проходов по датасету. Задайте 0, чтобы работать по макс. шагам.",
|
||||
saveSteps: "Шаги сохранения",
|
||||
saveStepsTooltip: "Сохранять чекпоинт каждые N шагов. 0 для отключения.",
|
||||
evalSteps: "Шаги оценки",
|
||||
evalStepsTooltip:
|
||||
"Доля от общего числа шагов обучения между оценками (0-1). Задайте 0, чтобы отключить оценку. Например, 0.01 = оценка каждый 1% шагов.",
|
||||
seed: "Seed",
|
||||
seedTooltip: "Случайный seed для воспроизводимости.",
|
||||
gradCheckpoint: "Чекпоинт градиента",
|
||||
gradCheckpointTooltip:
|
||||
"Обменять вычисления на память, пересчитывая активации.",
|
||||
none: "Нет",
|
||||
standard: "Стандартный",
|
||||
enablePacking: "Включить packing",
|
||||
assistantCompletionsOnly: "Только ответы ассистента",
|
||||
readMore: "Подробнее",
|
||||
},
|
||||
training: {
|
||||
title: "Обучение",
|
||||
description: "Мониторинг и управление обучением",
|
||||
chartNoDataTitle: "Пока нет данных обучения",
|
||||
chartNoDataDescription: "Начните обучение, чтобы увидеть прогресс loss",
|
||||
startTraining: "Начать обучение",
|
||||
starting: "Запуск...",
|
||||
loadingModel: "Загрузка модели...",
|
||||
checkingDataset: "Проверка датасета...",
|
||||
configLabel: "Конфигурация обучения",
|
||||
upload: "Загрузить",
|
||||
uploadConfigTooltip: "Загрузить сохранённую конфигурацию YAML",
|
||||
save: "Сохранить",
|
||||
saveConfigTooltip: "Скачать текущую конфигурацию как YAML",
|
||||
reset: "Сбросить",
|
||||
resetConfigTooltip: "Сбросить к значениям модели по умолчанию",
|
||||
configLoaded: "Конфигурация загружена",
|
||||
failedToLoadConfig: "Не удалось загрузить конфигурацию",
|
||||
invalidYamlFile: "Недопустимый файл YAML",
|
||||
failedToReadFile: "Не удалось прочитать файл",
|
||||
parametersReset: "Параметры сброшены к значениям модели по умолчанию",
|
||||
audioIncompatible:
|
||||
"Эта модель не поддерживает аудио. Переключитесь на модель с поддержкой аудио или выберите не-аудио датасет.",
|
||||
visionIncompatible:
|
||||
"Текстовая модель несовместима с мультимодальным датасетом. Переключитесь на модель зрения или выберите текстовый датасет.",
|
||||
cancelTitle: "Отменить обучение",
|
||||
cancelDescription: "Вы хотите отменить текущий запуск обучения?",
|
||||
continueAction: "Продолжить обучение",
|
||||
cancelAction: "Отменить обучение",
|
||||
stopTitle: "Остановить обучение",
|
||||
stopDescription: "Выберите, как остановить текущий запуск обучения.",
|
||||
stopAction: "Остановить",
|
||||
stopping: "Остановка...",
|
||||
stopAndSave: "Остановить и сохранить",
|
||||
compareInChat: "Сравнить в чате",
|
||||
exportModel: "Экспортировать модель",
|
||||
milestone: "Веха",
|
||||
halfwayDone: "Половина позади. Обучение прошло 50%.",
|
||||
doneNextStep:
|
||||
"Обучение завершено. Следующий шаг: сравните выводы базовой и дообученной модели.",
|
||||
},
|
||||
history: {
|
||||
title: "История",
|
||||
emptyTitle: "Пока нет запусков обучения",
|
||||
emptyDescription:
|
||||
"Пока нет запусков обучения. Запустите первое обучение на вкладке «Настройка».",
|
||||
loadError: "Не удалось загрузить запуски обучения",
|
||||
deleteError: "Не удалось удалить запуск обучения. Повторите попытку.",
|
||||
retry: "Повторить",
|
||||
loadMore: "Загрузить ещё",
|
||||
loading: "Загрузка...",
|
||||
loadingRun: "Загрузка запуска обучения...",
|
||||
runNotFound: "Запуск не найден",
|
||||
deleteTitle: "Удалить запуск обучения?",
|
||||
deleteDescription:
|
||||
"Это безвозвратно удалит этот запуск обучения и все его метрики. Это действие нельзя отменить.",
|
||||
runCount: "{count} запусков",
|
||||
oneRun: "1 запуск",
|
||||
resume: "Продолжить",
|
||||
resumeTraining: "Продолжить обучение",
|
||||
resuming: "Продолжение...",
|
||||
deleteRun: "Удалить запуск",
|
||||
loss: "Loss",
|
||||
steps: "Шаги",
|
||||
lossTrendSparkline: "Спарклайн тренда loss",
|
||||
relativeJustNow: "только что",
|
||||
relativeMinutesAgo: "{count} мин назад",
|
||||
relativeHoursAgo: "{count} ч назад",
|
||||
relativeDaysAgo: "{count} дн назад",
|
||||
status: {
|
||||
completed: "Завершено",
|
||||
stopped: "Остановлено",
|
||||
error: "Ошибка",
|
||||
running: "Выполняется",
|
||||
continued: "Продолжено",
|
||||
},
|
||||
message: {
|
||||
completed: "Обучение завершено",
|
||||
stopped: "Обучение остановлено",
|
||||
running: "Обучение выполняется",
|
||||
errored: "Ошибка обучения",
|
||||
},
|
||||
copyPreviewLink: "Копировать ссылку предпросмотра",
|
||||
previewLinkCopied: "Ссылка предпросмотра скопирована",
|
||||
previewLinkCopyFailed: "Не удалось скопировать ссылку",
|
||||
},
|
||||
charts: {
|
||||
settings: "Настройки графика",
|
||||
settingsDescription:
|
||||
"Настройте отображение графика, пока обучение продолжается.",
|
||||
openSettings: "Открыть настройки графика",
|
||||
viewWindow: "Окно просмотра",
|
||||
viewWindowDescription: "Показывать только последние шаги или всю историю.",
|
||||
window: "Окно",
|
||||
all: "Все",
|
||||
trainingLoss: "Loss обучения",
|
||||
trainingLossDescription: "Управление наложениями и EMA-сглаживанием.",
|
||||
smoothing: "Сглаживание",
|
||||
smoothingDescription: "Двигайте вправо для большего сглаживания. `0` = без обработки.",
|
||||
showRawLoss: "Показывать сырой loss",
|
||||
showSmoothedLoss: "Показывать сглаженный loss",
|
||||
showAverageLine: "Показывать линию среднего",
|
||||
scaleAndCleanup: "Масштаб и очистка",
|
||||
linear: "Линейный",
|
||||
log: "Логарифмический",
|
||||
noClip: "Без обрезки",
|
||||
clipP99: "Обрезка p99",
|
||||
clipP95: "Обрезка p95",
|
||||
lossAxis: "Ось loss",
|
||||
gradientNormAxis: "Ось нормы градиента",
|
||||
learningRateAxis: "Ось скорости обучения",
|
||||
resetDefaults: "Сбросить к умолчанию",
|
||||
loss: "Loss",
|
||||
smoothed: "Сглажено",
|
||||
evalLoss: "Eval Loss",
|
||||
learningRate: "Скорость обучения",
|
||||
lr: "LR",
|
||||
gradNorm: "Норма градиента",
|
||||
gradientNorm: "Норма градиента",
|
||||
step: "Шаг {step}",
|
||||
averageValue: "среднее {value}",
|
||||
waitingForFirstEvaluationStep: "Ожидание первого шага оценки...",
|
||||
evaluationNotConfigured: "Оценка не настроена",
|
||||
evalChartWillAppear: "График появится по достижении eval_steps",
|
||||
setEvalDatasetAndSteps:
|
||||
"Задайте датасет для оценки и eval_steps для отслеживания eval loss",
|
||||
},
|
||||
progress: {
|
||||
title: "Прогресс обучения",
|
||||
liveMetrics: "Метрики обучения в реальном времени",
|
||||
exportGguf: "Экспортировать в GGUF",
|
||||
openConfig: "Открыть конфигурацию обучения",
|
||||
configLabel: "Конфигурация обучения",
|
||||
hyperparams: "Гиперпараметры",
|
||||
epochs: "Эпохи",
|
||||
batchSize: "Размер батча",
|
||||
learningRate: "Скорость обучения",
|
||||
optimizer: "Оптимизатор",
|
||||
maxSteps: "Макс. шагов",
|
||||
contextLength: "Длина контекста",
|
||||
warmupSteps: "Шаги прогрева",
|
||||
rank: "Ранг",
|
||||
alpha: "Alpha",
|
||||
dropout: "Dropout",
|
||||
variant: "Вариант",
|
||||
epoch: "Эпоха {value}",
|
||||
percentComplete: "{percent}% завершено",
|
||||
stepProgress: "Шаг {current} / {total}",
|
||||
loss: "Loss",
|
||||
lr: "LR",
|
||||
gradNorm: "Норма градиента",
|
||||
project: "Проект",
|
||||
model: "Модель",
|
||||
method: "Метод",
|
||||
elapsed: "Прошло: {value}",
|
||||
eta: "Осталось: {value}",
|
||||
stepsPerSecond: "{value} шаг/с",
|
||||
noStepsPerSecond: "-- шаг/с",
|
||||
tokens: "Токены: {value}",
|
||||
gpuMonitor: "Монитор GPU",
|
||||
live: "В реальном времени",
|
||||
utilization: "Загрузка",
|
||||
temperature: "Температура",
|
||||
vram: "VRAM",
|
||||
power: "Мощность",
|
||||
phase: {
|
||||
idle: "Простой",
|
||||
downloadingModel: "Загрузка модели",
|
||||
downloadingDataset: "Загрузка датасета",
|
||||
loadingModel: "Загрузка модели",
|
||||
loadingDataset: "Загрузка датасета",
|
||||
configuring: "Настройка",
|
||||
training: "Обучение",
|
||||
completed: "Завершено",
|
||||
error: "Ошибка",
|
||||
stopped: "Остановлено",
|
||||
},
|
||||
},
|
||||
trainingStart: {
|
||||
ready: "Готово",
|
||||
downloading: "Загрузка",
|
||||
preparing: "Подготовка",
|
||||
left: "осталось {eta}",
|
||||
downloaded: "загружено {size}",
|
||||
terminalStart: "> обучение unsloth начинается...",
|
||||
preparingResources: "> Подготовка модели и датасета...",
|
||||
gettingReady: "> Мы готовим всё для вашего запуска...",
|
||||
waitingForFirstStep: "> {message} | ожидание первого шага... ({step})",
|
||||
resumingTraining: "Продолжение обучения...",
|
||||
startingTraining: "начало обучения...",
|
||||
dataset: "Датасет",
|
||||
datasetStreaming: "Датасет: потоковая передача (без полной загрузки)",
|
||||
modelWeights: "Веса модели",
|
||||
},
|
||||
tour: {
|
||||
guidedTour: "Обзорный тур",
|
||||
},
|
||||
},
|
||||
} satisfies DeepPartialMessageTree<typeof en>;
|
||||
|
|
@ -22,6 +22,9 @@ export const zhCN = {
|
|||
shutdown: "关闭服务",
|
||||
},
|
||||
shell: {
|
||||
beta: "BETA",
|
||||
brand: "unsloth",
|
||||
product: "Unsloth Studio",
|
||||
accountMenu: "{name} 账号菜单",
|
||||
updateAvailable: "有可用更新",
|
||||
aria: {
|
||||
|
|
@ -93,6 +96,7 @@ export const zhCN = {
|
|||
general: "通用",
|
||||
profile: "个人资料",
|
||||
appearance: "外观",
|
||||
resources: "系统",
|
||||
chat: "聊天",
|
||||
connections: "连接",
|
||||
apiKeys: "API",
|
||||
|
|
@ -128,6 +132,51 @@ export const zhCN = {
|
|||
chatDefaults: "聊天默认设置",
|
||||
autoTitleNewChats: "自动为新聊天命名",
|
||||
autoTitleNewChatsDescription: "根据第一条消息生成简短标题。",
|
||||
helperLlm: {
|
||||
sectionTitle: "辅助 LLM",
|
||||
preloadOnStartup: "启动时预缓存辅助 LLM",
|
||||
preloadOnStartupDescription:
|
||||
"启动时在后台下载 AI Assist 辅助模型。默认关闭;AI Assist 仍可按需获取。",
|
||||
disabledByEnv:
|
||||
"已由后端环境中的 UNSLOTH_HELPER_MODEL_DISABLE 禁用。",
|
||||
loadError: "加载辅助 LLM 设置失败。",
|
||||
saveError: "保存辅助 LLM 设置失败。",
|
||||
},
|
||||
modelAutoSwitch: {
|
||||
sectionTitle: "模型自动切换(OpenAI API)",
|
||||
enable: "按请求切换模型",
|
||||
enableDescription:
|
||||
"当兼容 OpenAI 的请求指定了另一个已下载的 GGUF 时,先加载它再提供服务。默认关闭;未知名称将继续使用已加载的模型。",
|
||||
idleUnload: "空闲自动卸载",
|
||||
idleUnloadDescription:
|
||||
"空闲达到该秒数后卸载模型以释放 VRAM;下次请求会重新加载。设为 0 则保持加载。",
|
||||
idleNeedsEnable:
|
||||
"开启“按请求切换模型”,以便已卸载的模型在下次使用时重新加载。",
|
||||
idleActiveViaEnv:
|
||||
"空闲自动卸载已通过 UNSLOTH_MODEL_IDLE_TTL 环境变量启用。",
|
||||
loadError: "加载模型自动切换设置失败。",
|
||||
saveError: "保存模型自动切换设置失败。",
|
||||
idleError: "请输入整数秒数(0 或以上)。",
|
||||
},
|
||||
previewSharing: {
|
||||
sectionTitle: "预览分享",
|
||||
enableLabel: "公开预览链接",
|
||||
enableDescription:
|
||||
"让任何持有签名链接的人无需登录即可与完成的模型聊天。关闭后将下线公开预览界面;已分享的链接将失效。",
|
||||
loadError: "加载预览分享设置失败。",
|
||||
saveError: "保存预览分享设置失败。",
|
||||
revokeLabel: "撤销所有预览链接",
|
||||
revokeDescription:
|
||||
"轮换签名密钥,使你分享过的所有链接失效。新复制的链接仍可用。",
|
||||
revokeAction: "撤销链接",
|
||||
revoking: "撤销中...",
|
||||
revokeConfirmTitle: "撤销所有预览链接?",
|
||||
revokeConfirmDescription:
|
||||
"你分享过的每个预览链接都将立即失效。此操作无法撤销。",
|
||||
revokeConfirmAction: "撤销所有链接",
|
||||
revoked: "所有预览链接已撤销",
|
||||
revokeError: "无法撤销预览链接",
|
||||
},
|
||||
notifications: {
|
||||
sectionTitle: "通知",
|
||||
showLlamaUpdates: "llama.cpp 更新通知",
|
||||
|
|
@ -142,7 +191,31 @@ export const zhCN = {
|
|||
sectionTitle: "上传",
|
||||
maxUploadSize: "训练数据集上传上限",
|
||||
maxUploadSizeDescription:
|
||||
"适用于训练数据集上传。默认值为 {defaultSize} MB。",
|
||||
"默认值为 {defaultSize} MB。",
|
||||
},
|
||||
rag: {
|
||||
sectionTitle: "文档与 RAG",
|
||||
embeddingModel: "Embedding 模型",
|
||||
embeddingModelDescription:
|
||||
"用于为文档建立索引和搜索的 Hugging Face 模型或本地路径。默认值为 {defaultModel}。",
|
||||
reindexWarning:
|
||||
"仅影响新建立索引的文档。更改模型后请重新上传已有文档。",
|
||||
emptyError: "请输入 Hugging Face 模型 ID 或本地路径。",
|
||||
loadError: "加载 embedding 模型设置失败。",
|
||||
saveError: "保存 embedding 模型失败。",
|
||||
saved: "Embedding 模型已保存。",
|
||||
saveAnyway: "仍然保存",
|
||||
resetAction: "重置为默认值",
|
||||
},
|
||||
storage: {
|
||||
sectionTitle: "存储",
|
||||
modelsFolder: "模型文件夹",
|
||||
modelsFolderDescription: "已下载模型的存储位置。",
|
||||
openAction: "打开",
|
||||
copyAction: "复制路径",
|
||||
copied: "路径已复制",
|
||||
openError: "无法打开文件夹",
|
||||
copyError: "无法复制路径",
|
||||
},
|
||||
resetPreferences: {
|
||||
sectionTitle: "危险区域",
|
||||
|
|
@ -158,7 +231,7 @@ export const zhCN = {
|
|||
},
|
||||
profile: {
|
||||
title: "个人资料",
|
||||
description: "更新你在 Unsloth 中显示的个人资料。",
|
||||
description: "你的个人资料在 Unsloth 中的显示方式。",
|
||||
changePicture: "更换头像",
|
||||
displayName: "显示名称",
|
||||
nickname: "Unsloth 应该怎么称呼你?",
|
||||
|
|
@ -186,6 +259,7 @@ export const zhCN = {
|
|||
title: "语言",
|
||||
label: "显示语言",
|
||||
description: "选择 Unsloth 使用的语言。",
|
||||
autoDetect: "自动检测",
|
||||
},
|
||||
theme: {
|
||||
title: "主题",
|
||||
|
|
@ -201,9 +275,73 @@ export const zhCN = {
|
|||
compactSidebarDescription: "保持侧边栏展开,而不是折叠为图标。",
|
||||
},
|
||||
},
|
||||
resources: {
|
||||
title: "系统",
|
||||
description: "监控此 Studio 服务器的硬件和存储。",
|
||||
liveUpdates: "实时更新",
|
||||
floatingWindow: "悬浮窗口",
|
||||
disableOverlay: "禁用悬浮层",
|
||||
liveMonitor: {
|
||||
title: "实时监控",
|
||||
cpu: "CPU",
|
||||
ram: "RAM",
|
||||
disk: "磁盘",
|
||||
vram: "VRAM",
|
||||
cpuCores: "{logical} 逻辑核心 / {physical} 物理核心",
|
||||
currentLoad: "当前负载",
|
||||
free: "{value} 可用",
|
||||
noGpu: "无可见 GPU",
|
||||
},
|
||||
gpu: {
|
||||
title: "GPU 设备",
|
||||
noGpu: "未检测到可见 GPU。上方仅显示 CPU 资源。",
|
||||
unknownDevice: "未知 GPU",
|
||||
deviceWithIndex: "GPU {index}",
|
||||
vramUtilization: "VRAM",
|
||||
used: "已用 {value}",
|
||||
free: "{value} 可用",
|
||||
total: "共 {value}",
|
||||
},
|
||||
storage: {
|
||||
title: "存储",
|
||||
systemDisk: "系统磁盘",
|
||||
diskUsage: "已用 {used} / {total}",
|
||||
diskFree: "{free} 可用",
|
||||
modelsFolder: "模型文件夹",
|
||||
modelsFolderDescription: "已下载模型的存储位置。",
|
||||
openAction: "打开",
|
||||
copyAction: "复制路径",
|
||||
copied: "路径已复制",
|
||||
openError: "无法打开文件夹",
|
||||
copyError: "无法复制路径",
|
||||
},
|
||||
environment: {
|
||||
title: "环境",
|
||||
backend: "后端",
|
||||
python: "Python",
|
||||
torch: "Torch",
|
||||
transformers: "Transformers",
|
||||
uptime: "运行时长",
|
||||
processMemory: "进程内存",
|
||||
notInstalled: "未安装",
|
||||
unknown: "未知",
|
||||
},
|
||||
},
|
||||
chat: {
|
||||
title: "聊天",
|
||||
description: "管理此设备上保存的聊天记录。",
|
||||
modelDisclaimer: "显示模型免责声明",
|
||||
modelDisclaimerDescription:
|
||||
"在聊天框下方显示“LLM 可能会出错”。",
|
||||
artifacts: {
|
||||
title: "Canvas",
|
||||
collapseHtmlBlocks: "折叠 HTML 块",
|
||||
collapseHtmlBlocksDescription:
|
||||
"Canvas 模式会自动折叠完整 HTML。开启此项可在关闭 Canvas 时也折叠代码块中的 HTML 文档。",
|
||||
allowNetworkAccess: "允许 Canvas 访问网络",
|
||||
allowNetworkAccessDescription:
|
||||
"允许 Canvas 预览从 CDN 加载脚本、样式、字体、媒体和网络资源。若需完全离线预览请保持关闭。",
|
||||
},
|
||||
data: "数据",
|
||||
exportHistory: "导出聊天记录",
|
||||
exportHistoryDescription: "将所有聊天和消息下载为 JSON 文件。",
|
||||
|
|
@ -284,8 +422,10 @@ export const zhCN = {
|
|||
usageTools: "工具",
|
||||
exampleCurlTools: "curl + 工具",
|
||||
examplePythonTools: "Python + 工具",
|
||||
exampleJavaScriptTools: "JavaScript + 工具",
|
||||
exampleCurlAdvanced: "curl + 高级",
|
||||
examplePythonAdvanced: "Python + 高级",
|
||||
exampleJavaScriptAdvanced: "JavaScript + 高级",
|
||||
osUnix: "Linux / macOS / WSL",
|
||||
osWindows: "Windows",
|
||||
secureHttps: "安全 HTTPS",
|
||||
|
|
@ -296,6 +436,12 @@ export const zhCN = {
|
|||
copy: "复制",
|
||||
copied: "已复制",
|
||||
setupDocs: "设置文档:",
|
||||
codingAgents: "编程智能体",
|
||||
codingAgentsHint:
|
||||
"针对此服务器启动编程智能体。它会使用已加载的模型;本地服务器会自动生成 API 密钥,远程服务器则会将其包含在命令中。",
|
||||
codingAgentsSwap: "可将 claude 替换为 codex、openclaw、opencode、hermes 或 pi。",
|
||||
codingAgentDetected: "已安装在本机",
|
||||
codingAgentsDetectedHint: "本机检测到:{agents}。",
|
||||
relativeNever: "从未",
|
||||
relativeJustNow: "刚刚",
|
||||
relativeHoursAgo: "{count} 小时前",
|
||||
|
|
@ -437,12 +583,12 @@ export const zhCN = {
|
|||
searchModels: "搜索模型...",
|
||||
searching: "搜索中...",
|
||||
noModelsFound: "未找到模型",
|
||||
needsVram: "约需 {vram}GB 显存(GPU:{gpu}GB)",
|
||||
tightVram: "约 {vram}GB 显存(在 {gpu}GB 上偏紧)",
|
||||
vramEstimate: "约 {vram}GB 显存",
|
||||
needsVram: "约需 {vram}GB VRAM(GPU:{gpu}GB)",
|
||||
tightVram: "约 {vram}GB VRAM(在 {gpu}GB 上偏紧)",
|
||||
vramEstimate: "约 {vram}GB VRAM",
|
||||
method: "方法",
|
||||
methodTooltip:
|
||||
"QLoRA 使用 4 位量化以最大限度降低显存。LoRA 使用 16 位。Full 会更新所有权重。CPT(持续预训练)在原始文本上训练,使模型适配新领域,不使用聊天格式。",
|
||||
"QLoRA 使用 4 位量化以最大限度降低 VRAM。LoRA 使用 16 位。Full 会更新所有权重。CPT(持续预训练)在原始文本上训练,使模型适配新领域,不使用聊天格式。",
|
||||
readMore: "了解更多",
|
||||
fullFineTune: "全量微调",
|
||||
checkingToken: "正在检查 token...",
|
||||
|
|
@ -528,7 +674,7 @@ export const zhCN = {
|
|||
accessKeyId: "访问密钥 ID",
|
||||
accessKeyIdPlaceholder: "AKIAIOSFODNN7EXAMPLE",
|
||||
secretAccessKey: "秘密访问密钥",
|
||||
secretAccessKeyPlaceholder: "您的 AWS 秘密访问密钥",
|
||||
secretAccessKeyPlaceholder: "你的 AWS 秘密访问密钥",
|
||||
useIamRole: "使用 IAM 角色",
|
||||
useIamRoleTooltip: "使用 IAM 角色凭证而非访问密钥(推荐用于 EC2/SageMaker)",
|
||||
testConnection: "测试连接",
|
||||
|
|
@ -604,9 +750,9 @@ export const zhCN = {
|
|||
cosine: "余弦",
|
||||
},
|
||||
batchSize: "批大小",
|
||||
batchSizeTooltip: "每步处理的样本数。越高占用越多显存。",
|
||||
batchSizeTooltip: "每步处理的样本数。越高占用越多 VRAM。",
|
||||
gradAccum: "梯度累积",
|
||||
gradAccumTooltip: "在不增加显存的情况下模拟更大的批大小。",
|
||||
gradAccumTooltip: "在不增加 VRAM 的情况下模拟更大的批大小。",
|
||||
weightDecay: "权重衰减",
|
||||
weightDecayTooltip: "L2 正则化,用于防止过拟合。",
|
||||
warmupSteps: "预热步数",
|
||||
|
|
@ -620,7 +766,7 @@ export const zhCN = {
|
|||
seed: "随机种子",
|
||||
seedTooltip: "用于复现的随机种子。",
|
||||
gradCheckpoint: "梯度检查点",
|
||||
gradCheckpointTooltip: "通过重算激活以时间换显存。",
|
||||
gradCheckpointTooltip: "通过重算激活以时间换 VRAM。",
|
||||
none: "无",
|
||||
standard: "标准",
|
||||
enablePacking: "启用 packing",
|
||||
|
|
@ -706,6 +852,9 @@ export const zhCN = {
|
|||
running: "训练进行中",
|
||||
errored: "训练出错",
|
||||
},
|
||||
copyPreviewLink: "复制预览链接",
|
||||
previewLinkCopied: "预览链接已复制",
|
||||
previewLinkCopyFailed: "无法复制链接",
|
||||
},
|
||||
charts: {
|
||||
settings: "图表设置",
|
||||
|
|
@ -749,6 +898,7 @@ export const zhCN = {
|
|||
progress: {
|
||||
title: "训练进度",
|
||||
liveMetrics: "实时训练指标",
|
||||
exportGguf: "导出为 GGUF",
|
||||
openConfig: "打开训练配置",
|
||||
configLabel: "训练配置",
|
||||
hyperparams: "超参数",
|
||||
|
|
@ -809,6 +959,7 @@ export const zhCN = {
|
|||
resumingTraining: "正在继续训练...",
|
||||
startingTraining: "正在开始训练...",
|
||||
dataset: "数据集",
|
||||
datasetStreaming: "数据集:流式传输(无需完整下载)",
|
||||
modelWeights: "模型权重",
|
||||
},
|
||||
tour: {
|
||||
|
|
|
|||
|
|
@ -6,23 +6,45 @@ import { en } from "./locales/en";
|
|||
import { zhCN } from "./locales/zh-CN";
|
||||
import { ptBR } from "./locales/pt-br";
|
||||
import { ja } from "./locales/ja";
|
||||
import { es } from "./locales/es";
|
||||
import { hi } from "./locales/hi";
|
||||
import { ar } from "./locales/ar";
|
||||
import { fr } from "./locales/fr";
|
||||
import { ru } from "./locales/ru";
|
||||
import { de } from "./locales/de";
|
||||
import { ko } from "./locales/ko";
|
||||
import type { InterpolationValues, MessageKey } from "./types";
|
||||
|
||||
// dir sets documentElement.dir; Arabic stays ltr (CSS still physical-direction) but renders rtl via bidi.
|
||||
export const LOCALES = {
|
||||
en: { label: "English", nativeLabel: "English" },
|
||||
"zh-CN": { label: "Chinese (Simplified)", nativeLabel: "简体中文" },
|
||||
"pt-BR": { label: "Portuguese (Brazil)", nativeLabel: "Português (Brasil)" },
|
||||
"ja": { label: "Japanese", nativeLabel: "日本語" },
|
||||
en: { label: "English", nativeLabel: "English", dir: "ltr" },
|
||||
"zh-CN": { label: "Chinese (Simplified)", nativeLabel: "简体中文", dir: "ltr" },
|
||||
ja: { label: "Japanese", nativeLabel: "日本語", dir: "ltr" },
|
||||
ko: { label: "Korean", nativeLabel: "한국어", dir: "ltr" },
|
||||
es: { label: "Spanish", nativeLabel: "Español", dir: "ltr" },
|
||||
"pt-BR": { label: "Portuguese (Brazil)", nativeLabel: "Português (Brasil)", dir: "ltr" },
|
||||
fr: { label: "French", nativeLabel: "Français", dir: "ltr" },
|
||||
de: { label: "German", nativeLabel: "Deutsch", dir: "ltr" },
|
||||
ru: { label: "Russian", nativeLabel: "Русский", dir: "ltr" },
|
||||
hi: { label: "Hindi", nativeLabel: "हिन्दी", dir: "ltr" },
|
||||
ar: { label: "Arabic", nativeLabel: "العربية", dir: "ltr" },
|
||||
} as const;
|
||||
|
||||
export type Locale = keyof typeof LOCALES;
|
||||
export type TranslationKey = MessageKey<typeof en>;
|
||||
|
||||
export const messages = {
|
||||
en,
|
||||
export const messages = {
|
||||
en,
|
||||
"zh-CN": zhCN,
|
||||
ja,
|
||||
ko,
|
||||
es,
|
||||
"pt-BR": ptBR,
|
||||
ja
|
||||
fr,
|
||||
de,
|
||||
ru,
|
||||
hi,
|
||||
ar,
|
||||
} as const;
|
||||
|
||||
const PLACEHOLDER_PATTERN = /\{([a-zA-Z0-9_]+)\}/g;
|
||||
|
|
@ -56,7 +78,8 @@ function interpolate(
|
|||
}
|
||||
|
||||
function warnMissingEnglishMessage(key: string): void {
|
||||
if (import.meta.env.DEV) {
|
||||
// Optional chain so translate() also works outside Vite (Node tooling).
|
||||
if (import.meta.env?.DEV) {
|
||||
console.warn(`[i18n] Missing English translation for key "${key}".`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue