サーバを立てるにはmlx_lm.serverコマンドを使用します (実コマンドはインストール時のハイフンと違いアンダースコアなので注意)。Dify (や他の API クライアント) が別のホストで動いているとか、他のサーバがポートを使用している等という場合は、下の例のようにオプションを指定してあげます。ボクは Dify が別の Mac で動いていて、テキスト読み上げ (text-to-speech) サーバが動いていたりするので、それぞれを指定しています。オプションの詳細はmlx_lm --helpを見てください。--log-levelは付けなくても問題ありません。
mlx_lm.server --host 0.0.0.0 --port 8585 --log-level INFO
こんな表示が出れば動いているはずです。
% mlx_lm.server --host 0.0.0.0 --port 8585 --log-level INFO
/Users/handsome/Documents/Python/FastMLX/.venv/lib/python3.11/site-packages/mlx_lm/server.py:682: UserWarning: mlx_lm.server is not recommended for production as it only implements basic security checks.
warnings.warn(
2024-12-15 21:33:25,338 - INFO - Starting httpd at 0.0.0.0 on port 8585...
ダウンロードが完了したら Ctrl + C でサーバを一度終了します。あ、ちなみにこの方法でダウンロードしたモデルは、LM Studio からも読めますので、どちらも試す場合はコマンドで入れる方法が容量削減になります (ただしフォルダ名は人にきびしい)。
モデルを指定して API サーバを立ち上げる
モデルの保存場所は~/.cache/huggingface/hub/の中で、今回の例ではmodels--mlx-community--QwQ-32B-Preview-4bitというフォルダになります。サーバを立ち上げるコマンドに渡すパスはさらに深く、snapshotの中、config.jsonファイルが含まれるフォルダとなります。そちらを指定して API サーバを立ち上げるコマンドはこんな感じです:
API サーバは、仮想環境内から以下コマンドで実行できます。モデルとトークナイザの読み込みに時間がかかります。
python server_speech_fastapi.py
しばらく待って、こうなれば準備完了です。
10-12 19:06:26 | DEBUG | __init__.py:130 | pyopenjtalk worker server started
10-12 19:06:27 | INFO | bert_models.py:92 | Loaded the Languages.JP BERT model from /Users/handsome/Documents/Python/Style-Bert-VITS2-Mac/bert/deberta-v2-large-japanese-char-wwm
10-12 19:06:27 | INFO | bert_models.py:154 | Loaded the Languages.JP BERT tokenizer from /Users/handsome/Documents/Python/Style-Bert-VITS2-Mac/bert/deberta-v2-large-japanese-char-wwm
10-12 19:06:27 |WARNING | tts_model.py:397 | No model files found in model_assets/.cache, so skip it
10-12 19:06:27 | INFO | server_speech_fastapi.py:116 | Loading models...
10-12 19:06:27 | INFO | server_speech_fastapi.py:123 | The maximum length of the text is 20000. If you want to change it, modify config.yml. Set limit to -1 to remove the limit.
10-12 19:06:27 |WARNING | server_speech_fastapi.py:129 | CORS allow_origins=['*']. If you don't want, modify config.yml
10-12 19:06:27 | INFO | server_speech_fastapi.py:338 | server listen: http://127.0.0.1:5055
10-12 19:06:27 | INFO | server_speech_fastapi.py:339 | API docs: http://127.0.0.1:5055/docs
10-12 19:06:27 | INFO | server_speech_fastapi.py:340 | Input text length limit: 20000. You can change it in server.limit in config.yml
[rank0]: File "/Users/handsome/Documents/Python/Style-Bert-VITS2-Mac/.venv/lib/python3.11/site-packages/torch/autograd/graph.py", line 825, in _engine_run_backward
[rank0]: return Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
[rank0]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[rank0]: RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
というわけで Mac ユーザの皆さん、ボクが MPS 化を完成させるのを待つよりも、地道に CPU で学習させた方が速いですよ。
Web UI にいる女子キャラや日本語が得意ということから、日本人の女の子をいくつか描かせたのですが全くイメージと違い、manga 調で競争している女子を描かせても顔が破綻していて多方面から怒られそうだったので、アプローチを全く変えました。深い森からやっと抜け出せた喜びと今の季節感を盛り込んだ、情緒的なトップ絵です。
Date: 2024年10月4日 23:12:07
Model: realisticVision-v51VAE_original_768x512_cn
Size: 768 x 512
Include in Image: photo realistic beautiful nature in the late summer. fresh air and sunshine
def split_audio_whisper(audio_path, audio_name, target_dir='processed'):
global model
if model is None:
model = WhisperModel(model_size, device="cpu", compute_type="float32")
audio = AudioSegment.from_file(audio_path)
max_len = len(audio)
def decode(self, codes: torch.Tensor, scale: tp.Optional[torch.Tensor] = None):
"""Decode the given codes to a reconstructed representation, using the scale to perform
audio denormalization if needed.
Args:
codes (torch.Tensor): Int tensor of shape [B, K, T]
scale (torch.Tensor, optional): Float tensor containing the scale value.
Returns:
out (torch.Tensor): Float tensor of shape [B, C, T], the reconstructed audio.
"""
emb = self.decode_latent(codes)
#out = self.decoder(emb)
# Below if block is added based on https://github.com/facebookresearch/audiocraft/issues/31
if emb.device.type == 'mps':
# XXX: Since mps-decoder does not work, cpu-decoder is used instead
out = self.decoder.to('cpu')(emb.to('cpu')).to('mps')
else:
out = self.decoder(emb)
out = self.postprocess(out, scale)
# out contains extra padding added by the encoder and decoder
return out
python demos/audiogen_mps_app.py "heavy rain with a clap of thunder" "knocking on a wooden door" "people whispering in a cave" "racing cars passing by"
/Users/handsome/Documents/Python/AudioCraft_MPS/.venv/lib/python3.11/site-packages/torch/nn/utils/weight_norm.py:30: UserWarning: torch.nn.utils.weight_norm is deprecated in favor of torch.nn.utils.parametrizations.weight_norm.
warnings.warn("torch.nn.utils.weight_norm is deprecated in favor of torch.nn.utils.parametrizations.weight_norm.")
0.wav を生成
かかった時間: 61.05 秒
1.wav を生成
かかった時間: 61.1 秒
2.wav を生成
かかった時間: 61.16 秒
3.wav を生成
かかった時間: 61.22 秒
M2 Max 32GB RAM だと、メモリプレッシャーが低い状態から始めれば、5秒のファイルは 60秒前後、10秒のファイルは 100秒前後で生成されます。
# Main function that builds window and adds page. Also, adds audio file and dialogs that are invisible as overlay.
async def main(page: ft.Page):
page.title = 'Speech + Subtitles Player'
page.window_height = 800
page.theme_mode=ft.ThemeMode.SYSTEM
page.update()
# Appends audio as an overlay to the page.
async def load_audio():
page.overlay.append(app.audio1)
page.update()
# Creates an instance of AudioSubPlayer class. Passes load_audio for the instance to append audio to the page.
app = AudioSubPlayer(load_audio)
page.add(app)
# Adds dialog instance methods to the page.
page.overlay.extend([app.pick_speech_file_dialog, app.pick_text_file_dialog,
app.export_as_srt_dialog, app.export_as_txt_dialog])
page.update()
def __init__(self, load_audio):
super().__init__()
self.position = 0
self.duration = 0
self.isPlaying = False
self.load_audio = load_audio
# == Controls ==
# Audio control with default properties
self.audio1 = ft.Audio(
src='',
volume=1,
balance=0,
playback_rate=1,
on_loaded=self.loaded,
on_position_changed = self.position_changed,
on_state_changed = self.playback_completed,
)
# Path of the audio file
self.base_dir = ft.Text(value=f"Base Directory: ")
# Open speech file button
self.speech_file_button = ft.ElevatedButton(
text='Open Speech File',
icon=ft.icons.RECORD_VOICE_OVER_OUTLINED,
width=210,
on_click=self.pre_pick_speech_file,
)
# Speech file picker control
self.pick_speech_file_dialog = ft.FilePicker(on_result=self.pick_speech_file_result)
# Speech file name
self.speech_file_name = ft.Text(value='← Click to open a speech file.')
# Alert dialog that opens if subtitle was edited but not saved when Open Speech File button is clicked.
self.speech_save_or_cancel_dialog = ft.AlertDialog(
modal=True,
title=ft.Text('Change not saved.'),
content=ft.Text('Do you want to discard the change?'),
actions=[
#ft.TextButton('Save', on_click=self.save_then_open, tooltip='Save then open another file.'),
ft.TextButton('Open without save', on_click=self.open_speech_without_save, tooltip='Change will be lost.'),
ft.TextButton('Cancel', on_click=self.close_speech_save_or_cancel_dialog),
]
)
# Open text file button
self.text_file_button = ft.ElevatedButton(
text='Open SRT/TXT File',
icon=ft.icons.TEXT_SNIPPET_OUTLINED,
on_click=self.pre_pick_text_file,
disabled=True,
width=210,
)
# Text file picker control
self.pick_text_file_dialog = ft.FilePicker(on_result=self.pick_text_file_result)
# Text file name
self.text_file_name = ft.Text(value='No file selected.')
# Save button to update edited subtitles. No dialog, it just overwrites current text file.
self.save_button = ft.ElevatedButton(
text='Save',
icon=ft.icons.SAVE_OUTLINED,
tooltip='Update current SRT/TXT file.',
disabled=True,
on_click=self.save_clicked
)
# Export as SRT button which opens a save dialog. Only available when SRT is open because SRT needs timestamp.
self.export_as_srt_button = ft.ElevatedButton(
text = 'SRT',
icon=ft.icons.SAVE_ALT,
on_click=self.export_as_srt,
disabled=True,
tooltip='Export as SRT file.'
)
# Export as SRT file picker
self.export_as_srt_dialog = ft.FilePicker(on_result=self.export_as_srt_result)
# Export as TXT button which opens a save dialog. TXT has not timestamp, subtitle text only.
self.export_as_txt_button = ft.ElevatedButton(
text = 'TXT',
icon=ft.icons.SAVE_ALT,
on_click=self.export_as_txt,
disabled=True,
tooltip='Export as TXT file.'
)
# Export as TXT file picker
self.export_as_txt_dialog = ft.FilePicker(on_result=self.export_as_txt_result)
# Export button to open a dialog (not in use)
self.export_button = ft.ElevatedButton(
text='Export as...',
icon=ft.icons.SAVE_ALT,
on_click=self.open_export_dialog,
disabled=True,
)
# Export as dialog (not in use)
self.export_dialog = ft.AlertDialog(
modal = True,
title = ft.Text('Export text as...'),
content = ft.Text('Plesae select a file type.'),
actions = [
ft.TextButton('SRT', on_click=self.export_as_srt, tooltip='Subtitles with timestamps'),
ft.TextButton('TXT', on_click=self.export_as_txt, tooltip='Subtitles only (no timestamps)'),
#ft.TextButton('CSV', on_click=self.export_csv, tooltip='Comma separated value'),
# I guess no one needs subtitles in CSV...
ft.TextButton('Cancel', on_click=self.close_export_dialog),
],
actions_alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
)
# Alert dialog that opens if subtitle was edited but not saved when Open SRT/TXT File button is clicked.
self.text_save_or_cancel_dialog = ft.AlertDialog(
modal=True,
title=ft.Text('Change not saved.'),
content=ft.Text('Do you want to discard the change?'),
actions=[
#ft.TextButton('Save', on_click=self.save_then_open, tooltip='Save then open another file.'),
ft.TextButton('Open without save', on_click=self.open_text_without_save, tooltip='Change will be lost.'),
ft.TextButton('Cancel', on_click=self.close_text_save_or_cancel_dialog),
]
)
# Audio position slider
self.audio_slider = ft.Slider(
min = 0,
value = int(self.position/10000),
label = "{value}ms",
on_change = self.slider_changed,
)
# Current playing position and duration of audio file
self.position_text = ft.Text(value='Current position')
self.duration_text = ft.Text(value='Duration (hh:mm:ss,nnn)')
# Rewinds 5 seconds
self.rewind_button = ft.ElevatedButton(
icon=ft.icons.REPLAY_5,
text="5 secs",
tooltip='Rewind 5 secs',
on_click=self.rewind_clicked,
disabled=True,
)
# Play/Pause button. After loading audio file, this button will always be focused (space/enter to play/pause).
self.play_button = ft.ElevatedButton(
icon=ft.icons.PLAY_ARROW,
text = "Play",
on_click=self.play_button_clicked,
disabled=True,
)
# 1.5x faster toggle switch
self.faster_sw = ft.Switch(
label='1.5x',
value=False,
on_change=self.playback_rate,
)
# Auto scroll toggle switch
self.sub_scroller_sw = ft.Switch(
label='Auto scroll',
value=True,
)
# Area to add subtitles as buttons
self.subs_view = ft.Column(
spacing = 5,
height= 400,
width = float("inf"),
scroll = ft.ScrollMode.ALWAYS,
auto_scroll=False,
)
# Notification bar control at the bottom
self.notification_bar=ft.SnackBar(
content=ft.Text('Speech + Subtitle Player'),
duration=2000,
bgcolor=ft.colors.BLUE_GREY_700,
)
# Called once audio file is loaded. Enable/disable buttons, create subtitles list, etc.
async def loaded(self, e):
self.audio_slider.max = int(await self.audio1.get_duration_async())
self.duration_text.value = f'{ms_to_hhmmssnnn(self.audio_slider.max)}'
self.audio_slider.divisions = self.audio_slider.max//60
# Enables buttons if associated text file exists.
if self.text_file != 'No Text File.':
# Call function to create the list of subtitles, self.subtitles.
self.subtitles = create_subtitles(self.text_file)
self.save_button.text = 'Save'
self.save_button.disabled=False
self.export_button.disabled=False
self.export_as_srt_button.disabled=False
self.export_as_txt_button.disabled=False
# Disable buttons if associated text file does not eixt.
else:
self.save_button.disabled=True
self.export_button.disabled=True
self.export_as_srt_button.disabled=True
self.export_as_txt_button.disabled=True
self.subtitles = []
self.speech_file_button.autofocus=False
self.speech_file_button.update()
self.play_button.disabled=False
self.play_button.focus()
self.play_button.autofocus=True
self.play_button.update()
self.rewind_button.disabled=False
self.text_file_button.disabled=False
self.subs_view.controls.clear()
# Create buttons of subtitles from the list self.subtitles.
if self.subtitles != []:
# .txt or .srt file
for i in range(len(self.subtitles)):
index = self.subtitles[i][0]
start_time = self.subtitles[i][1]
# .txt file (timestap is dummy, 55:55:55,555) disable buttons.
if self.subtitles[0][1]== 201355555:
self.sub_scroller_sw.value=False
self.sub_scroller_sw.disabled=True
self.export_dialog.actions[0].disabled=True
self.export_as_srt_button.disabled=True
# .srt file
else:
self.sub_scroller_sw.value=True
self.sub_scroller_sw.disabled=False
self.sub_scroller_sw.update()
end_time = self.subtitles[i][2]
text = self.subtitles[i][3]
# Create button instance of each subtitle. Include methods and controls for the instance to call or update.
sub = SubButton(index, start_time, end_time, text, self.sub_time_clicked, self.play_button,
self.save_button, self.subtitles)
# Add button to the subtitle button area, subs_view.
self.subs_view.controls.append(sub)
# Call snackbar to show a notification.
notification = f'Subtitle file loaded: {os.path.basename(self.text_file)}'
await self.open_notification_bar(notification)
# No text file found. Call snackbar to show an alert.
else:
notification = f'Subtitle file (.srt or .txt) not found.'
await self.open_notification_bar(notification, type='error')
print('Subtitle file not found.')
self.update()
on_position_changed にはプロパティがあり、メソッドで e として受け取っています。e.data には再生位置 (経過時間) がミリ秒で入っていますので、ここではスライダの位置を変更するためにその値をaudio_slider コントロールの value プロパティに代入しています。また、position_text コントロールの value に読みやすい形に変換した値を入れています。これはスライダの左端に表示されることになります。
if (self.sub_scroller_sw.value == True) and (self.text_file_name.value != 'No Text File.'):
self.scroll_to(self.audio_slider.value)
self.update()
ここで判定しているのは、字幕のオートスクロールのスイッチの状態と、字幕ファイルの有無です。字幕ファイルは、読み込めなかったときに “No Text File.” と表示させているので、表示内容自体をフラグとして利用しています。そして、それぞれが真の場合、字幕をスクロールするメソッドscroll_toに引数self.audio_slider.valueを渡しています。最後のself.update()で、ここのメソッド自身としては再生時間の更新がされます。
# Create button instance of each subtitle. Include methods and controls for the instance to call or update.
sub = SubButton(index, start_time, end_time, text, self.sub_time_clicked, self.play_button,
self.save_button, self.subtitles)
# When the timestamp is clicked, jump to its position and play if not playing.
async def sub_time_clicked(self, start_time):
self.audio1.seek(int(start_time))
if self.isPlaying == False:
await self.play_button_clicked(start_time)
self.update()
# Called once Open Speech File button is clicked to pause playback and check if changes saved.
async def pre_pick_speech_file(self, e):
if self.isPlaying == True:
await self.play_button_clicked(e)
if self.save_button.text == '*Save':
#print('Save is not done.')
await self.speech_save_or_cancel()
else:
await self.pick_speech_file()
# Opens a dialog if change is not saved.
async def speech_save_or_cancel(self):
self.page.dialog = self.speech_save_or_cancel_dialog
self.speech_save_or_cancel_dialog.open = True
self.page.update()
# Alert dialog that opens if subtitle was edited but not saved when Open Speech File button is clicked.
self.speech_save_or_cancel_dialog = ft.AlertDialog(
modal=True,
title=ft.Text('Change not saved.'),
content=ft.Text('Do you want to discard the change?'),
actions=[
#ft.TextButton('Save', on_click=self.save_then_open, tooltip='Save then open another file.'),
ft.TextButton('Open without save', on_click=self.open_speech_without_save, tooltip='Change will be lost.'),
ft.TextButton('Cancel', on_click=self.close_speech_save_or_cancel_dialog),
]
)
未保存の変更があるときに開くダイアログです。セーブせずにファイルを開く Open without save と、キャンセルしてダイアログを閉じる Cancel ボタンが配置されています。ここからセーブもできるようにしたかったのですがうまくいかず、Save ボタンはコメントで残っています。
# Saves as .txt file.
async def save_as_txt(self, save_file_name):
with open(save_file_name, 'w') as txt:
for i in self.subtitles:
for j in range(len(i)):
if j % 4 == 3:
txt.write('%s\n' % i[j])
notification = f'Subtitle saved as a TXT file: {os.path.basename(save_file_name)}'
await self.open_notification_bar(notification)
self.update()
# Exports current open SRT file as another SRT file.
async def export_as_srt(self, e):
if os.path.splitext(self.text_file)[1] == '.srt':
suggested_file_name = os.path.basename(self.text_file).split('.', 1)[0]+'_'+datetime.now().strftime("%Y%m%d%H%M")+'.srt'
self.export_as_srt_dialog.save_file(
dialog_title='Export as an SRT file',
allowed_extensions=['srt'],
file_name = suggested_file_name,
file_type=ft.FilePickerFileType.CUSTOM,
)
# Checks result of Export as SRT File Picker and passes absolute path to self.save_as_srt if exists.
async def export_as_srt_result(self, e: ft.FilePicker.result):
if e.path:
await self.save_as_srt(e.path)
TXT で書き出すメソッドのコードを開く
# Exports current open text file as a TXT file.
async def export_as_txt(self, e):
if os.path.exists(os.path.splitext(self.text_file)[0]+'.txt'):
suggested_file_name = os.path.basename(self.text_file).split('.', 1)[0]+'_'+datetime.now().strftime("%Y%m%d%H%M")+'.txt'
else:
suggested_file_name = os.path.basename(self.text_file).split('.', 1)[0]+'.txt'
self.export_as_txt_dialog.save_file(
dialog_title='Export as a TXT file',
allowed_extensions=['txt'],
file_name = suggested_file_name,
file_type=ft.FilePickerFileType.CUSTOM,
)
# Checks result of Export as TXT File Picker and passes absolute path to self.save_as_txt if exists.
async def export_as_txt_result(self, e: ft.FilePicker.result):
if e.path:
await self.save_as_txt(e.path)
# Notification bar control at the bottom
self.notification_bar=ft.SnackBar(
content=ft.Text('Speech + Subtitle Player'),
duration=2000,
bgcolor=ft.colors.BLUE_GREY_700,
)
# Opens notification bar with given text. If type is 'error', shows message longer with caution color.
async def open_notification_bar(self, notification, type='normal'):
if type == 'normal':
self.notification_bar.content=ft.Text(notification, color=ft.colors.LIGHT_BLUE_ACCENT_400)
self.notification_bar.bgcolor=ft.colors.BLUE_GREY_700
elif type == 'error':
self.notification_bar.content=ft.Text(notification, color=ft.colors.RED)
self.notification_bar.bgcolor=ft.colors.YELLOW
self.notification_bar.duration=4000
self.notification_bar.open=True
self.notification_bar.update()
# === BUILD METHOD ===
def build(self):
# Start time button
self.display_start_time = ft.TextButton(text=f"{ms_to_hhmmssnnn(int(self.start_time))}",
# Disable jump button if loaded text is TXT, no timestamp.
disabled=(self.start_time==201355555),
# When enabled, jump to the key when clicked.
key=self.index,
width=130,
on_click=self.jump_clicked,)
# Subtitle text button in display view. Click to edit.
self.display_text= ft.TextButton(text=f"{self.text}",
on_click=self.edit_clicked,
tooltip='Click to edit')
# Placeholder of subtitle text button in edit view.
self.edit_text = ft.TextField(expand=1)
# Put controls together. Left item is the key=index.
self.display_view = ft.Row(
alignment=ft.MainAxisAlignment.START,
controls=[
ft.Text(value=self.index, width=30),
self.display_start_time,
self.display_text,
]
)
# Change tool tip of start time button which is only clickable for SRT.
if self.start_time==201355555:
self.display_start_time.tooltip='Jump not available'
else:
self.display_start_time.tooltip='Click to jump here'
# Subtitle edit view visible when clicked.
self.edit_view = ft.Row(
visible=False,
#alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
#vertical_alignment=ft.CrossAxisAlignment.CENTER,
controls=[
self.edit_text,
ft.IconButton(
icon=ft.icons.DONE_OUTLINE_OUTLINED,
tooltip='Update Text',
on_click=self.save_clicked,
),
ft.IconButton(
icon=ft.icons.CANCEL_OUTLINED,
tooltip='Close wihout change',
on_click=self.cancel_clicked,
)
]
)
return ft.Column(controls=[self.display_view, self.edit_view])
Flet は割と簡単にモダンなデザインでアプリが作れるので、そこが大きな魅力です。GUI の構成要素となるボタンやテキストはもちろん、音声ファイルの処理やスライダー、通知やダイヤログなど、あらかた必要なものはそろっており、細かいところは気にせずに配置していくだけで、とりあえずアプリっぽいものが作れてしまいます。持っていないので想像でしかないのですが、質の良い 3D プリンタを手に入れたのと近い気がしています。3D モデルデータが実物になるように、Python のコードが触れるようになるという感覚です。
オフィシャルのドキュメントは充実しており、うまく理解できれば自分のアプリに利用できます。基本的に全ての機能はウェブブラウザで動く設計なので、実際に触って試せる Live example も多数用意されていて、いじりながら自分のアプリに使う部品を探す作業も楽しいです。このギャラリーに行けば、おそらくほとんどのコントロールや機能のサンプルを試し、GitHub で実際のコードの確認が行えるので、すごく助かります。
--prompt "what is the mlx-lm python module?" ダブルクォーテーションの中に質問を書きます。日本語も使えます
実際に出力された内容はこちらです。先ほどインストールしたモジュール mxl_lm の説明をしてくれています。”developed by the Melting Potato project” と言っていますが、間違っている感じがします。サンプルがまずかったか他の部分も確実に評価はできませんが、3B のモデルでもあり、鵜呑みにはできません。
000 --prompt "what is the mlx-lm python module?"
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
==========
Prompt: <|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
what is the mlx-lm python module?<|im_end|>
<|im_start|>assistant
The mlx-lm Python module is a stand-alone machine learning library developed by the Melting Potato project. It is designed to simplify the process of training and deploying machine learning models in Python applications.
The mlx-lm module provides a high-level interface for working with machine learning algorithms, allowing developers to easily integrate them into their Python applications. It simplifies the process by providing a unified interface for various machine learning frameworks, such as TensorFlow, PyTorch, and Scikit-learn.
Here are some key features of the mlx-lm module:
1. **Model Training**: mlx-lm provides a simple and consistent API for training machine learning models. It supports various types of models, including regression, classification, and deep learning models, and allows developers to train models using large datasets.
2. **Model Deployment**: mlx-lm provides a flexible and easy-to-use interface for deploying machine learning models in production environments. It supports various deployment options, such as web services, REST APIs, or microservices, and allows developers to integrate models into their existing applications without requiring extensive knowledge of the underlying infrastructure.
3. **Model Evaluation**: mlx-lm provides a comprehensive set of tools for evaluating and analyzing machine learning models. It supports various evaluation metrics, such as accuracy, precision, recall, and F1 score, and allows developers to compare different models and assess their performance.
4. **Model Optimization**: mlx-lm provides a set of techniques for optimizing machine learning models. It supports techniques like feature selection, hyperparameter tuning, and model compression, allowing developers to improve the performance of their models without compromising their efficiency.
5. **Integration with Other Libraries**: mlx-lm is designed to be easily integrated with other Python libraries, such as NumPy, Pandas, and SciPy, allowing developers to leverage their existing codebase while benefiting from the powerful machine learning capabilities provided by mlx-lm.
To use the mlx-lm module, you need to install it first by running the following command:
```
pip install mlx-lm
```
Once installed, you can import the module into your Python code and start working with machine learning models.
Please note that mlx-lm is an open-source project, and you can contribute to its development by participating in the project's community forum, mailing lists, or by submitting bug reports and feature requests.<|im_end|>
==========
Prompt: 213.558 tokens-per-sec
Generation: 38.486 tokens-per-sec
Stable Code Instruct 3B は日本語もイケる
前回、Hugging Face にあるサンプルをいじって実行したときには日本語のスピードが遅くて無理と思いましたが、コマンドプロンプトで実行する方法であれば英語と同程度のスピードで回答が出てきます。以下、プロンプトとその回答です。コードを書いてもらえれば実行することで評価ができますし、Stable Code Instruct の本領がここにあります。
python -m mlx_lm.generate --model stable-code-instruct-3b \
--max-tokens 1000 --prompt "python で、入力された数値を西暦とし、\
閏年かどうかを判定するプログラムを書いてください。\
また、閏年の場合は、2月29日の曜日 (day of the week) も答えるようにしてくだい。"
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
==========
Prompt: <|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
python で、入力された数値を西暦とし、閏年かどうかを判定するプログラムを書いてください。また、閏年の場合は、2月29日の曜日 (day of the week) も答えるようにしてくだい。<|im_end|>
<|im_start|>assistant
以下は、Pythonで西暦を判定し、閏年かどうかを判定するプログラムです。閏年の場合は、2月29日の曜日も答えます。
```python
def is_leap_year(year):
"""
判定する条件は、以下の通り
1. 年は4で割り切れる場合、または100で割り切れる場合、または400で割り切れる場合、それぞれ2, 5, 0と対応
2. 上記以外の年は、閏年とは判定しない
"""
if (year % 4 == 0 and year % 100!= 0) or (year % 400 == 0):
return True
return False
def day_of_week(year, month, day):
"""
月曜日で0、火曜日で1、....、土曜日で6、日曜日で7
"""
t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
year -= month < 3
return (year + year // 4 - year // 100 + year // 400 + t[month-1] + day) % 7
year = int(input("Enter a year: "))
if is_leap_year(year):
print(f"{year} is a leap year.")
print(f"The day of the week for February 29 is {['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day_of_week(year, 2, 29)]}.")
else:
print(f"{year} is not a leap year.")
```
注意: 年は0-basedで入力する必要があり、誤入力時にエラーが出る可能性があります。
また、曜日も0-basedで表現される点についても注意が必要です。
上記プログラムは、閏年の判定基準は、世界的な共通的な定義であり、西暦法的な定義でありません。例えば、日本の历法でも、明治40年 (1873) に改西暦法施設が始まり、以後は、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定しません。日本の共通的な定義では、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定する必要があります。
上記プログラムは、西暦法的な定義で判定しています。西暦法的な定義で判定すると、明治以降の年は、4、100、400で割り切れる有り、閏年とは判定しません。
ごめんなさい。
---
注意: 入力された年は、0-basedであり、1-basedで表現される日付を入力する必要があり、週の曜日も0-basedで表現される点についても注意が必要です。
上記プログラムは、西暦法的な定義で閏年を判定しています。世界的な共通的な定義で判定すると、閏年とは判定しません。西暦法的な定義でも、閏年とは判定しません。
ごめんなさい。<|im_end|>
==========
Prompt: 600.106 tokens-per-sec
Generation: 32.308 tokens-per-sec
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
import time
start_time = time.time()
tokenizer = AutoTokenizer.from_pretrained("stabilityai/stable-code-instruct-3b", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("stabilityai/stable-code-instruct-3b", torch_dtype=torch.float16, trust_remote_code=True)
model.eval()
model.to(torch.device("mps"))
inputs = tokenizer('''
please rewrite a python code that uses numpy module to without numpy module.
source code is below
index = numpy.argmin(numpy.abs(numpy.array(end_time) – e))
please note that end_time is a list of integers that contains from smallest number to the largest, and e is float
''', return_tensors='pt').to(model.device)
tokens = model.generate(
**inputs,
max_new_tokens=2048,
temperature=0.5,
top_p=0.95,
top_k=100,
do_sample=True,
use_cache=True
)
output = tokenizer.batch_decode(tokens[:, inputs.input_ids.shape[-1]:], skip_special_tokens=False)[0]
print(output)
end_time = time.time()
elapsed_time = round(end_time - start_time, 1)
print('############################')
print(f"処理にかかった時間: {elapsed_time}秒")
print('############################')
% python test.py
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
Loading checkpoint shards: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:02<00:00, 1.10s/it]
Setting `pad_token_id` to `eos_token_id`:0 for open-end generation.
```python
import numpy as np
end_time = [1,2,3,4,5]
e = 2.3
index = np.argmin(np.abs(np.array(end_time) - e))
print(index)
```
Here is the code rewritten without numpy module:
```python
end_time = [1,2,3,4,5]
e = 2.3
index = min(range(len(end_time)), key = lambda i: abs(end_time[i]-e))
print(index)
```
In the rewritten code, we use the built-in `min` function in Python along with a `lambda` function as the key to find the minimum index based on the absolute difference between the element in the list and the float `e`. The `range(len(end_time))` is used to generate a sequence of indices for the list.
Note: Although the code is rewritten without using numpy, the performance may not be as efficient as the numpy version due to the absence of vectorized operations. Numpy provides vectorized operations which are more efficient for large datasets.<|im_end|>
<|endoftext|>
############################
処理にかかった時間: 37.6秒
############################
% python ja_test.py
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
Loading checkpoint shards: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:02<00:00, 1.49s/it]
Setting `pad_token_id` to `eos_token_id`:0 for open-end generation.
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff = diff
index = i
return index
```
ごめんなさい。ありがちですが、私は numpy を使った方が早いです。
---
私は numpy を使わない方向で、end_time をソートして e に近い値を探索する方法を考えています。以下のコードで実現できます。
```python
def find_nearest(end_time, e):
end_time.sort()
min_diff = float('inf')
index = -1
for i, time in enumerate(end_time):
diff = abs(time - e)
if diff < min_diff:
min_diff<|endoftext|>
############################
処理にかかった時間: 989.5秒
############################
Image by Stable Diffusion
今回のは良いのができました。母国語以外で考えるのって難しいよね。
Date: 2024年3月31日 23:45:34
Model: realisticVision-v20_split-einsum
Size: 512 x 512
Include in Image: realistic, masterpiece, best quality, retro future, smart multi-lingual engineer running in a small yard
# Called when slider position is changed and scroll to subtitle with the nearest end_time.
async def scroll_to(self, e):
end_time = [item[2] for item in self.subtitles]
# Numpy is only used below:
#index = np.argmin(np.abs(np.array(end_time) - e))
# Below works without using Numpy:
index = min(range(len(end_time)), key=lambda i: abs(end_time[i]-e))
key=str(self.subtitles[index][0])
self.subs_view.scroll_to(key=key, duration =1000)
self.update()
% flet build macos --build-version "1.0.1" --template flet-build-template --include-packag
es flet_audio
Creating Flutter bootstrap project...OK
Customizing app icons and splash images...OK
Generating app icons...Because flet_audio <0.20.1 depends on flet ^0.20.0 and flet_audio >=0.20.1 <0.20.2 depends on flet ^0.20.1, flet_audio <0.20.2 requires flet ^0.20.0.
And because flet_audio ^0.20.2 depends on flet ^0.20.2 and flet_audio >=0.21.0 <0.21.1 depends on flet ^0.21.0, flet_audio <0.21.1 requires flet ^0.20.0 or
^0.21.0.
And because flet_audio >=0.21.1 <0.21.2 depends on flet ^0.21.1 and flet_audio >=0.21.2 depends on flet ^0.21.2, every version of flet_audio requires flet
^0.20.0 or >=0.21.0 <0.22.0.
So, because fletaudioplayback depends on both flet ^0.19.0 and flet_audio any, version solving failed.
You can try the following suggestion to make the pubspec resolve:
* Try upgrading your constraint on flet: dart pub add flet:^0.21.2
Error building Flet app - see the log of failed command above.
Include in Image: realistic, masterpiece, best quality, retro future, happy young guy partially gray hair with glasses jumping with big simle in front of a beautiful building