There is extremely little quality loss from dropping to 4-bit for LLMs, and that “extremely little” becomes “virtually unmeasurable” loss when going to 8-bit. No one should be running these models on local devices at fp16 outside of research, since fp16 makes them half as fast as q8_0 and requires twice as much RAM for no benefit.
If a model is inadequate for a task at 4-bit, then there's virtually no chance it's going to be adequate at fp16.
Microsoft has also been doing a lot of research into smaller models with the Phi series, and I would be surprised if Phi3 (or a hypothetical Phi4) doesn’t show up at some point under the hood.
I think this is using the OpenAI Whisper repo? If they want a real comparison, they should be comparing MLX to faster-whisper or insanely-fast-whisper on the 4090. Faster whisper runs sequentially, insanely fast whisper batches the audio in 30 second intervals.
We use whisper in production and this is our findings: We use faster whisper because we find the quality is better when you include the previous segment text. Just for comparison, we find that faster whisper is generally 4-5x faster than OpenAI/whisper, and insanely-fast-whisper can be another 3-4x faster than faster whisper.
FF's TTS is an important project for anyone who wants a trivial to use text-to-speech system. It's built into the browser so you can just run
wss = window.speechSynthesis;
for (let i = 0; i < wss.getVoices().length; ++i){
str = `Voice ${i} is ${wss.getVoices()[i].name}`;
s = new SpeechSynthesisUtterance(str);
s.voice = wss.getVoices()[i];
wss.speak(s);
console.log(str);
}
in the console to get various TTS examples. For some browsers, this can be done offline while others use a cloud based TTS system.
I am looking at the GitHub repo for the Malt library developed in the book https://github.com/themetaschemer/malt. It looks like they use Racket (Scheme) vectors to implement tensors. I experimented with loading Keras simple models into Racket several years ago: the built in math library matrix support was fast enough for my needs so the book software may be both pedagogical and useful for smaller problems.
EDIT: I have not tried the OpenBLAS Racket bindings here (https://github.com/soegaard/sci) but perhaps the low level tensor and tensor ops book code could be optimized,
SICP is mainly a book about how to structure systems. It also tells you how languages work, but in far less detail.
PLAI (this book) teaches you how languages work. It also tells you a bit about how to structure systems, but that is not its goal. In part that is not a goal because of the existence of books like SICP and, increasingly, DCIC [https://dcic-world.org/].
There are so many misconceptions on this thread about what makes a good quant trading strategy.
First of all, if you're shorting US equities and making 25% annually, that would be awesome. Heck, even being flat would be great because a strategy that is long SP500 could also short your equities and be delta-neutral and likely have a much lower volatility for the same return.
Second, so many people are mentioning commissions, trading fees, taxes and so on. Commissions and trading fees are much less than 1 basis point per trade if you use reputable brokerages. That would, at most, amount to a 1-2% in fees per year. Market impact matters but opening and closing auctions are very liquid and represent respectively more than 1% and 5% of the daily volume, probably even more for these kind of ETFs. Shorting fees are also quite small, in the range of 0-2% for liquid ETFs. If you don't hold positions overnight which is your case, you also don't pay to short!
Finally, here's what really matters. Returns by themselves don't matter. If you want a very high return strategy, you can short a long VIX ETF like VXX but every once in a while, you will be down more than a 100% ; it will bankrupt you if your available capital is less than the value of your short. You also need to look at your Sharpe ratio and maximum drawdown. Anyone somewhat experienced could tell you if the strategy is valid by having a look at plot of returns. If it's not too volatile, it could be a good strat.
> I am currently unable to work because macOS sends hashes of every opened executable to some server of theirs and when `trustd` and `syspolicyd` are unable to do so, the entire operating system grinds to a halt.
EDIT:
As others pointed out, I put this to my `/etc/hosts` file and refreshed it like so:
Can anyone recommend other books similar to this one?
Having done the Nand2Tetris course and started the Ray Tracer Challenge book I find I really like these books that guide you through a pretty complex project.
It helps you learn by doing while at the same time preventing you from falling into bad practices or getting overwhelmed.
I highly recommend Jean Moroney's blog. She digs deep into the psychology behind productivity and goal-setting. I found many unique insights in her articles. Thanks to her writing I've come to believe that procrastination often stems from deeper emotional issues or an unacknowledged clash of priorities (for example, when you try to force yourself to do something that you don't, in fact, want to do, the deeper issue is that you haven't resolved the clash between your short-time desires and your long-term goals).
You can read The Little Schemer and The Seasoned Schemer which are deceptively easy to work through but teach you concepts some CS grad students are ignorant of. Following it up with Structure and Interpretation of Computer Programs will make you a much stronger programmer.
You can work through Sedgewick's Algorithms course on Coursera to get a stronger foundation for the more technical aspects of compiler writing.
Since Common Lisp is a language standard (not an implementation) it is hard to provide a single set of instructions or guidelines that would work for all implementations. There are various implementations of Common Lisp that target native machine code, C code, bytecode, JVM, etc. So the build instructions, project structure, etc. depend on the target.
Here is a minimal example that builds a Lisp program into a binary executable with SBCL:
(defun main () (format t "hello, world~%"))
(sb-ext:save-lisp-and-die "hello" :executable t :toplevel 'main)
The SBCL-specific `save-lisp-and-die` function saves the Lisp process as a core image. The `:executable` argument includes the SBCL runtime in the image to ensure that the image is a standalone executable. This is why the executable for even a simple hello-world program tends to be quite large (30 MB to 50 MB)! The `:toplevel` argument specifies which function to run when the core file is run.
Here are some example commands to get you started:
$ cat hello.lisp
(defun main () (format t "hello, world~%"))
(sb-ext:save-lisp-and-die "hello" :executable t :toplevel 'main)
$ sbcl --script hello.lisp
$ ./hello
hello, world
If you would rather not have SBCL specific code in the Lisp source code file, then you could move the `sb-ext:save-lisp-and-die` call out of your source file to the SBCL command invocation. The source code now looks like this:
(defun main () (format t "hello, world~%"))
The shell commands now look like this:
$ cat hello.lisp
(defun main () (format t "hello, world~%"))
$ sbcl --load hello.lisp --eval "(sb-ext:save-lisp-and-die \"hello\" :executable t :toplevel 'main)"
$ ./hello
hello, world
By the way, there is also Buildapp[1] that provides a layer of abstraction for building executables from Lisp programs. It works with SBCL and CCL. It requires the toplevel function to be called with an argument though. Therefore the source code needs to be modified to:
(defun main (argv) (declare (ignore argv)) (format t "hello, world~%"))
Then Buildapp can be invoked like this:
$ cat hello.lisp
(defun main (argv) (declare (ignore argv)) (format t "hello, world~%"))
$ buildapp --load hello.lisp --entry main --output hello
;; loading file #P"/Users/susam/hello.lisp"
$ ./hello
hello, world
A fun and fairly simple project, with a surprisingly high ratio of usefullness to effort, is to write an interpreter for a concatenative language. Concatenative languages, like FORTH, can do a lot with very limited resources, making them good candidates for embedded systems.
If you want to play around with making your own concatenative language, it is actually surprisingly simple. Here is an overview of a step-by-step approach that can take you from a simple calculator to a full language with some optimization that would actually be quite reasonable to use in an embedded system.
So let's start with the calculator. We are going to have a data stack, and all operations will operate on the stack. We make a "dictionary" whose entries are "words" (basically names of functions). For each word in the dictionary, the dictionary contains a pointer to the function implementing that word.
We'll need six functions for the calculator: add, sub, mul, div, clr, and print. The words for these will be "+", "-", "x", "/", "clr", and "print". So our dictionary looks like this in C:
We need a main loop, which will be something like this (pseudocode):
while true
token = NextToken()
if token is in dictionary
call function from that dict entry
else if token is a number
push that number onto the data stack
Write NextToken, making it read from your terminal and parse into whitespace separated strings, implement add, sub, mul, div, clr, and print, with print printing the top item on the data stack on your terminal, and you've got yourself an RPN calculator. Type "2 3 + 4 5 + x print" and you'll get 45.
OK, that's fine, but we want something we can program. To get to that, we first extend the dictionary a bit. We add a flag to each entry allowing us to mark the entry as either a C code entry or an interpreted entry, and we add a pointer to an array of integers, and we add a count telling the length of that array of integers. When an entry is marked as C code, it means that the function implementing it is written in C, and the "func" field in the dictionary points to the implementing function. When an entry is marked as interpreted, it means that the pointer to an array of integers points to a list of dictionary offsets, and the function is implemented by invoking the functions of the referenced dictionary entries, in order.
A dictionary entry now looks something like this:
struct DictEntry {
char * word;
bool c_flag;
void (*func)(void);
int * def;
int deflen;
}
I recommend Prandoni & Vetterli's coursera class on Signal processing[1].
They have really made an effort to teach this in an intuitive manner
instead of just throwing equations at you. This was the course where
I finally really understood Fourier transforms in a visual way.
The other course I recommend is the Audio Signal processing class by Xavier Serra[2]
This is a practical class with lots of hands on programming examples and introduction
to useful open-source software tools.
I don't mean how to use a tool chain to compile higher level languages to WASM. I mean how to write the linear assembly bytecode as seen here on Wikipedia:
I have a Linux/Programming/Tech Career YouTube channel ( https://youtube.com/c/tutorialinux ) that just hit 50k subscribers (yay!), and it makes around $450/month in ad revenue.
I also made a poorly targeted and marketed practical system administration Udemy course last year, which does about $500/month.
These projects, along with a few other small things, are on track to make around $15k this year. That's after about 3 years of putting lots of time, effort, and love into creating content on YouTube.
Unfortunately that 'passive' income just barely approaches 10% of what I make at my full-time job (Sysadmin/Ops/Automation/DevOps? stuff), so the idea of working on my 'passive/hobby' projects full-time is not an attractive proposition yet.
I like building, running, and automating large distributed systems, so I'm not really itching to quit my full-time work and "just" be a teacher. The ideal situation would be 'regular' IT work 3 days a week, and working on YouTube, my own web apps, and additional tech courses the rest of the time.
My compilers course has all the lectures recorded, and has starter code for all the assignments provided. It provides all the parsers, and focuses on the backend, including memory management and various details of value representations.
This is just my materials, I don't have an associated platform with verification/certification. However, some folks from HN have previously done the course and emailed me after, and seem to have gotten some value out of it.
Not sure if I should share this, as it is a trivial and obvious thing to do. Recently I created a ramen-profitable on google play with currently a couple of thousand users.
The idea is to look for apps that have low ratings, high downloads and lots of recent comments, then make them better. You can use synonyms and the same niche category to increase visibility on google play. This is where the money is.
Rather than temporarily suspend vim to use the terminal you can get vim to suspend and resume itself with the exclamation mark command. This has the benefit of not wreaking havoc on your vim session and allowing you to read data into vim by prefixing with r.
For example
:!ls
will execute ls and show you the result (press enter to return)
:r!ls
will read the result of ls in for you
More usefully
:r!sed -n5,10p that/other/file
will read lines 5-10 from that other file.
However you will most often want to
:!make
:!up build
:!git status
:!git commit -am "Fixed #23"
I really disagree that this is madness. It may be madness to someone not used to coding in C. But if you code a lot of C you _will_ know when to use which one of these, and you will know that they're immensely useful.
For example, iterating and adding stuff to arrays:
array[index++] = object;
instead of
array[index] = object;
index += 1;
and the other way around:
array[++index] = object;
instead of:
index += 1;
array[index] = object;
There is no way you will miss incrementing your index here, or do it in the wrong place. This is so common, that as a C-programmer you WILL recognize this pattern.
It's even better when iterating pointers instead of integers. May I ask what the following means to you?
float *float_ptr;
float_ptr += 1;
I think writing ++float_ptr here is just much more clear. Incrementing pointers by integers just feels wrong when what you really are doing is incrementing it with sizeof(float_ptr).
I wrote an ebook ("Practice Makes Python", http://lerner.co.il/practice-makes-python ) for people who have learned Python basics, but want to gain fluency. I'm working on videos for a higher-tier offering, and then will start to market it more seriously.
I only launched the book about 1.5 months ago, and I'm at about $1500 in revenue. I'm definitely hoping to see greater income with the higher tiers (including video) and greater marketing. I'm also speaking with some companies about them buying site licenses of the book, which would increase the revenue even more.
I wrote a book[1] a year and a half ago that just recently crossed $42k in total revenue. These days it consistently earns $1.5k/mo without much further input from me, other than tweaks to the landing page copy and updates once in awhile when Stripe or Rails changes significantly.
I made two TypeScript videos for Pluralsight ("ES6 with TypeScript" and "Practical TypeScript Migration"). I put them together in the evenings and weekends using the knowledge I got at my day job and from working on TypeScript open source projects like grunt-ts (and a lot of research).
It was a lot of work, but it's a great passive income now that they're done, and I'm quite proud of how they turned out. The Pluralsight authors are a great professional network to be plugged-in with, and being an author is a pretty unique differentiator on your resume.